【问题标题】:How to create subscribe BehaviorSubject and return value of difference type如何创建订阅 BehaviorSubject 并返回不同类型的值
【发布时间】:2019-11-25 03:13:58
【问题描述】:

我创建了一个 Setting-Service,其中包含 2 个 BehaviorSubjects,如下所示:

settingNameSubject = new BehaviorSubject<SettingName>({});
SettingDataSubject = new BehaviorSubject<SettingData>({});

&lt;SettingData&gt; 包含对象列表,每个对象都有一个&lt;SettingName&gt;。

我必须创建一个 Setting-Name-Observable,它只订阅 settingNameSubject,并返回在 SettingDataSubject 中找到的值。

我使用了 combineLastest:

this.SettingName$ = this.SettingNameSubject.asObservable();
this.combinedOne = combineLatest(this.SettingName$, () => {
  return this.SettingDataSubjectValue.filter(item => item.name === this.SettingName$.getValue())
});

是否有不同的方法来解决可能的问题?

如果我想同时订阅 BehaviorSubject,我应该使用 combineLatest2 吗?

【问题讨论】:

  • 这些主题总是同步的吗?例如,当在SettingName$ 上调用next 而不是在SettingDataSubjectValue 上调用时会发生什么?如果这些是同步的,那么您可以创建一个返回两个值的主题。
  • 2 个主题始终同步。因为我有 2 个屏幕,设置调整和另一个屏幕使用设置来显示图表。当图表名称更改时,我通知设置服务和设置调整屏幕将根据图表名称更改。

标签: angular rxjs


【解决方案1】:

我有类似的情况,用户在一个页面上选择了一个产品,而另一个页面上的产品详细信息发生了变化。我只用一个像这样的 BehaviorSubject 来做:

  private productSelectedSubject = new BehaviorSubject<number>(0);
  // Expose the action as an observable for use by any components
  productSelectedAction$ = this.productSelectedSubject.asObservable();

   selectedProduct$ = combineLatest([
    this.products$,
    this.productSelectedAction$
  ]).pipe(
    map(([products, selectedProductId]) =>
      products.find(product => product.id === selectedProductId)
    ),
    tap(product => console.log('selectedProduct', product)),
    shareReplay(1)
  );

products$ 流包含数据:

  products$ = this.http.get<Product[]>(this.productsUrl)
    .pipe(
      tap(data => console.log('Products', JSON.stringify(data))),
      catchError(this.handleError)
    );

所以我将动作流 (BehaviorSubject) 与数据流(通过 http.get 获得)结合起来

由于详细信息页面订阅了selectedProduct$,因此每次将项目发送到productSelectedAction$ 流时,它都会自动更新。

不需要用另一个 BehaviorSubject 通知它。

有意义吗?

【讨论】:

    【解决方案2】:

    或许用switchMap更直观

    settingNameSubject.pipe(switchMap(name=>
      this.SettingDataSubject.pipe(filter(item => item.name === name))
    ))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-25
      • 1970-01-01
      • 2021-10-11
      • 1970-01-01
      • 2020-06-07
      • 1970-01-01
      • 2019-06-02
      相关资源
      最近更新 更多