我正试图等待几个状态片成为我的保护区中的true
。
我试过了:
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
return combineLatest([
this.store.select(
fromStore.selectProductsLoaded
),
this.store.select(fromStore.selectArticlesLoaded),
]).pipe(
map(([a, b]) => ({ a, b })),
filter(({ a, b}) => a && b),
first()
);
}
我需要这两个数据是true
,所以我想使用combineLatest
,但遇到了这个错误:Type 'Observable<{ a: boolean; b: boolean; }>' is not assignable to type 'Observable<boolean>'
相比之下,这种方法有效:
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
return this.store
.select(fromStore.selectProductsLoaded)
.pipe(
filter((loaded) => loaded),
take(1)
);
}
当您最终对来自商店的数据使用combineLatest
时,IMO您可以将其视为危险信号或代码气味。
如果您想组合来自存储的一些数据,请使用选择器。主要区别在于,combineLatest
只需要发射一次可观测到的,而不是至少发射两次(这将等待两者发射(。
它可能看起来如下:
const canActivateNameOfYourRoute = createSelector(
fromStore.selectProductsLoaded,
fromStore.selectArticlesLoaded,
(productsLoaded, articlesLoaded) => productsLoaded && articlesLoaded
);
class YourGuard {
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
return this.store.select(canActivateNameOfYourRoute).pipe(
filter(Boolean),
first()
);
}
}
之所以会出现此错误,是因为使用combineLatest可以传递一个可观测值数组,然后将其映射到结构为{a:boolean,b:boolean}的对象。
我想您希望基于这两个输入返回一个布尔值。
因此一个可能的解决方案是
.pipe(
map(([a, b]) => ({ a, b })),
filter(({ a, b}) => a && b),
map(values => {
// both a and b are true
if(values.a && values.b){
return true;
} else {
return false;
}
}),
first()
);