Angular: 更新一个行为主题
Angular: update a behaviorsubject
我在看一门关于 RxJs 的 angular 大学课程。一节描述了使用行为主体在商店服务中加载数据。
我试图在我的 angular 应用程序中实现它,方法是创建商店服务并在应用程序启动时对其进行初始化(我的 AppComponent):
@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 上,我调用存储服务 init() 函数来初始填充可观察对象:
this.storeService.init();
在我使用 assetStatuses$ 可观察对象(在下拉列表中)的组件(组件 A)上,我使用以下方法获取数据:
this.assetStatuses$ = this.storeService.getAssetStatues();
并将其绑定到我的下拉列表。这一切都很完美。
当我从状态组件(组件B)添加新状态时,我从组件调用商店服务中的刷新功能:
this.storeService.refreshAssetStatuses();
这似乎更新了商店中可观察到的 assetStatuses$,因为我可以控制它并且新添加的值在那里。但是,当我离开组件 A(使用下拉列表中的可观察对象的组件)并返回到它时,即使我在 ngOnInit 中调用存储服务,它也会保留旧值:this.storeService.getAssetStatues( );
我不知道为什么这是 return旧值。如果我在浏览器中重做,它们就会出现
感谢任何帮助。
编辑:
我还注意到一件事。在我的商店服务中,我有两个功能,一个用于更新可观察对象,另一个用于获取可观察对象,return 个不同的值。如果我先调用刷新函数,在添加新资产状态后,控制台显示它更新了 assetStatuses$ observable:
refreshAssetStatuses(): void {
this.appService.getAssetStatuses().subscribe(
(assetStatuses) => {
this.assetStatusesSubject.next(assetStatuses);
console.log('assetStatuses',this.assetStatuses$) // this has the new value
}
);
}
之后,当我调用获取可观察对象的函数(在同一服务中)时,控制台不显示新值:
getAssetStatuses() {
console.log('getAssetStatuses',this.assetStatuses$); // the new value is missing
return this.assetStatuses$;
}
我不明白这是怎么发生的,因为它们都指的是商店服务中的同一个可观察对象,而首先调用的刷新清楚地表明 assetStatuses$ 已更新。
我很困惑:(
编辑 2:
我忘记提及的另一件事是这两个组件是延迟加载的。我认为 provideIn: 'root' (因为 Angular 6)应该创建服务的单例实例。我正在研究这个以确保我的实施对于这种情况是正确的
我要检查的第一件事是确保在 AppComponent、组件 A 和组件 B 中对商店服务的引用是 public。
您也在推送到 this.businessUnitsSubject
,但可观察到的是基于 this.assetStatusSubject
推送到 this.assetStatusSubject
可能是您想要做的。
我的一个同事发现了这个问题。尝试对此进行测试时,我打开了两个浏览器选项卡。一个选项卡是组件 A,另一个是组件 B。行为主题特定于一个选项卡,它们不会在其他选项卡或其他浏览器中更新 windows。我认为至少它们会跨浏览器选项卡共享。需要了解的宝贵信息。
我在看一门关于 RxJs 的 angular 大学课程。一节描述了使用行为主体在商店服务中加载数据。
我试图在我的 angular 应用程序中实现它,方法是创建商店服务并在应用程序启动时对其进行初始化(我的 AppComponent):
@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 上,我调用存储服务 init() 函数来初始填充可观察对象:
this.storeService.init();
在我使用 assetStatuses$ 可观察对象(在下拉列表中)的组件(组件 A)上,我使用以下方法获取数据:
this.assetStatuses$ = this.storeService.getAssetStatues();
并将其绑定到我的下拉列表。这一切都很完美。
当我从状态组件(组件B)添加新状态时,我从组件调用商店服务中的刷新功能:
this.storeService.refreshAssetStatuses();
这似乎更新了商店中可观察到的 assetStatuses$,因为我可以控制它并且新添加的值在那里。但是,当我离开组件 A(使用下拉列表中的可观察对象的组件)并返回到它时,即使我在 ngOnInit 中调用存储服务,它也会保留旧值:this.storeService.getAssetStatues( );
我不知道为什么这是 return旧值。如果我在浏览器中重做,它们就会出现
感谢任何帮助。
编辑:
我还注意到一件事。在我的商店服务中,我有两个功能,一个用于更新可观察对象,另一个用于获取可观察对象,return 个不同的值。如果我先调用刷新函数,在添加新资产状态后,控制台显示它更新了 assetStatuses$ observable:
refreshAssetStatuses(): void {
this.appService.getAssetStatuses().subscribe(
(assetStatuses) => {
this.assetStatusesSubject.next(assetStatuses);
console.log('assetStatuses',this.assetStatuses$) // this has the new value
}
);
}
之后,当我调用获取可观察对象的函数(在同一服务中)时,控制台不显示新值:
getAssetStatuses() {
console.log('getAssetStatuses',this.assetStatuses$); // the new value is missing
return this.assetStatuses$;
}
我不明白这是怎么发生的,因为它们都指的是商店服务中的同一个可观察对象,而首先调用的刷新清楚地表明 assetStatuses$ 已更新。
我很困惑:(
编辑 2:
我忘记提及的另一件事是这两个组件是延迟加载的。我认为 provideIn: 'root' (因为 Angular 6)应该创建服务的单例实例。我正在研究这个以确保我的实施对于这种情况是正确的
我要检查的第一件事是确保在 AppComponent、组件 A 和组件 B 中对商店服务的引用是 public。
您也在推送到 this.businessUnitsSubject
,但可观察到的是基于 this.assetStatusSubject
推送到 this.assetStatusSubject
可能是您想要做的。
我的一个同事发现了这个问题。尝试对此进行测试时,我打开了两个浏览器选项卡。一个选项卡是组件 A,另一个是组件 B。行为主题特定于一个选项卡,它们不会在其他选项卡或其他浏览器中更新 windows。我认为至少它们会跨浏览器选项卡共享。需要了解的宝贵信息。