我在我的 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>
答案 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)
我建议创建一个选择器来组合这些状态。 https://github.com/timdeschryver/eslint-plugin-ngrx/blob/master/docs/rules/avoid-combining-selectors.md
答案 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;
});
}