无法使用 Ngrx 同时从不同商店获取最新状态

时间:2021-05-03 13:27:25

标签: angular ngrx ngrx-store redux-observable

我在我的 Angular 应用程序中使用 Ngrx 从商店获取数据。
我创建了多个存储:上下文、决策和状态,以在对象之间创建功能分离。

我有一个案例,UI 需要同时轮询来自 2 个不同商店的最新状态,以便它可以启用/禁用按钮。

这是一个示例,其中 titi 的状态在按钮被点击后从其他组件更新。
我的问题是,使用我的实际代码,我无法获得 this.titi 的最新状态!
这是我的代码:

export class MyComponent implements OnInit, OnDestroy {

   private titi: Titi;
   private toto: Toto;
   private unsubscribe$: Subject<void> = new Subject<void>();

   constructor(private store: Store<State>) {}

   ngOnInit() {

      this.store.pipe(
         select(selectTiti),
         takeUntil(this.unsubscribe$)
      ).subscribe(state => {
         this.titi= state.titi;
      });

      this.store.pipe(
         select(selectTata),
         takeUntil(this.unsubscribe$)
      ).subscribe(state => {
         this.tata= state.tata;
      });

   }

   public isBtnDisabled() {
      return this.titi === 'latest value of titi' && this.tata === 'latest value of tata';
   }

   ....

   ngOnDestroy(): void {
     this.unsubscribe$.next();
     this.unsubscribe$.complete();
   }
}

和用户界面:

<button [disabled] = 'isBtnDisabled()'></button>

3 个答案:

答案 0 :(得分:1)

您可以使用更被动的方式来做到这一点。 通过使用 combineLatest,如果值更改到存储中,您将获得每个选择器的最新值:

isDisabled$ = combineLatest(
  this.store.select(selectTiti),
  this.store.select(selectTata)
).pipe(
  map(([titi, tata]) => // do whatever you want to check the disabled status)
);

您可以在模板中使用异步管道进行订阅,这样您就不必依赖手动取消订阅组件:

<button [disabled] = 'isDisabled$ | async'></button>

所以最终的组件应该是这样的:

export class MyComponent {

  public isDisabled$: Observable<boolean> = combineLatest(
  this.store.select(selectTiti),
  this.store.select(selectTata)
  ).pipe(
    map(([titi, tata]) => // do whatever you want to check the disabled status)
  );

   constructor(private store: Store<State>) {}
}

答案 1 :(得分:0)

答案 2 :(得分:-2)

最后,结合我发现清晰且接近我的实现的商店的解决方案是:

ngOnInit() {
    this.store.pipe(
      select(selectTiti),
      withLatestFrom(this.store.pipe(select(selectTata))),
      takeUntil(this.unsubscribe$)
    ).subscribe(([titiState, tataState]) => {
      this.titi = titiState.titi;
      this.tata = tataState.tata;
    });
}