【发布时间】:2021-06-23 18:04:36
【问题描述】:
我正在观看关于 RxJs 的 Angular 大学课程。一节描述了使用行为主体在商店服务中加载数据。
我尝试通过创建商店服务并在应用启动时对其进行初始化(我的 AppComponent)在我的 Angular 应用中实现它:
@Injectable({
providedIn: 'root'
})
export class StoreService {
constructor(private appService: AppService) { }
private assetStatusSubject = new BehaviorSubject<IAssetStatusModel[]>([]);
assetStatuses$: Observable<IAssetStatusModel[]> = this.assetStatusSubject.asObservable();
init() {
this.appService.getAssetStatuses().subscribe(
(assetStatuses) => this.assetStatusSubject.next(assetStatuses)
);
}
getAssetStatues() {
return this.assetStatuses$;
}
refreshAssetStatuses () {
this.appService.getAssetStatuses().subscribe(
(assetStatuses) => {
this.assetStatusSubject.next(assetStatuses);
console.log('assetStatuses',this.assetStatuses$)
}
);
}
关键在于,这些很少更改的数据在应用程序的几个地方使用。以这种方式设置将避免每次加载某些组件时都必须进行多次 API 调用。
在 AppComponent 上,我调用 store service init() 函数来初始填充 observable:
this.storeService.init();
在我使用assetStatuses$ observable(在下拉列表中)的组件(组件A)上,我使用以下方法获取数据:
this.assetStatuses$ = this.storeService.getAssetStatues();
并将其绑定到我的下拉列表。这一切都很完美。
当我从状态组件(组件B)添加新状态时,我从组件调用存储服务中的刷新功能:
this.storeService.refreshAssetStatuses();
这似乎更新了商店中可观察到的assetStatuses$,因为我可以将其控制出来并且新增加的价值就在那里。但是,当我离开组件 A(在下拉列表中使用 observable 的组件)并返回到它时,即使我在 ngOnInit 中调用存储服务,它也会保留旧值:this.storeService.getAssetStatues( );
我不知道为什么这会返回旧值。如果我在浏览器中重新尝试一下,它们就会出现
感谢任何帮助。
编辑:
我还注意到一件事。在我的商店服务中,我有两个函数,一个用于更新 observable,另一个用于获取 observable,返回不同的值。如果我先调用刷新函数,添加新资产状态后,控制台显示它更新了assetStatuses$ observable:
refreshAssetStatuses(): void {
this.appService.getAssetStatuses().subscribe(
(assetStatuses) => {
this.assetStatusesSubject.next(assetStatuses);
console.log('assetStatuses',this.assetStatuses$) // this has the new value
}
);
}
之后,当我调用获取 observable 的函数(在同一服务中)时,控制台不会显示新值:
getAssetStatuses() {
console.log('getAssetStatuses',this.assetStatuses$); // the new value is missing
return this.assetStatuses$;
}
我不明白这是怎么发生的,因为它们都引用了商店服务中的同一个可观察对象,并且首先调用的刷新清楚地显示了 assetsStatuses$ 已更新。
我很困惑:(
编辑 2:
我还要提到的另一件事是这两个组件是延迟加载的。我认为 provideIn: 'root' (从 Angular 6 开始)应该创建服务的单例实例。我正在研究这个以确保我的实现对于这种情况是正确的
【问题讨论】:
-
不要直接引用组件中的 observable,而是尝试订阅它。
-
我也试过了:this.storeService.assetStatuses$.subscribe((data) => { console.log('data', data)});但数据变量仍然是旧数据。
-
你确定组件 A 真的被销毁了吗?尝试在 ngOnDestroy 中添加一个 console.log/debugger 并检查它是否真的被销毁了。
-
Lars:我编辑了我的帖子以显示商店服务中更新 observable 的函数具有新值。但是当我调用返回 observable 的函数(在同一个 servcie 中)时,它没有新值。在帖子中查看我的编辑。
-
确保您的 StoreService 仅在一个 providers 数组中提供,否则它将为每个组件创建一个新实例。
标签: angular rxjs behaviorsubject