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。我认为至少它们会跨浏览器选项卡共享。需要了解的宝贵信息。