是否有一种方法可以使可观察对象既以空数组开始,又在未通过筛选时默认为空数组。
以下是我使用的内容
inactiveItems$: Observable<any[]> = combineLatest(this.store.select(fromAuth.getAuthState), this.showInactiveItems$).pipe(
filter(([authState, showInactiveItems]: any) => authState?.roles?.isAgent === true && showInactiveItems === true),
switchMap(([authState, showInactiveItems]) => this.db.collection('items', ref => ref.where('agentId', '==', authState.uid).where('active', '==', false)).valueChanges({ idField: 'id' }).pipe(
catchError(err => of([]))
)),
startWith([])
);
一些解释:
1( showInactiveItems是一个布尔行为主题
2( authstate来自NgRx存储
3( 可从switchMap观察到的是AngularFire
我尝试过使用defaultIfEmpty运算符,但它只在可观察对象完成或添加类似take(1(时有效,但对于AngularFire的可观察对象,它需要保持打开状态,以便在进行更改时在应用程序中更新。
我也试过摆弄IIF创建操作符,但当条件发生变化时,我不知道如何让可观察的再次运行。
filter
将停止流。相反,应该使用map
返回一个值,该值确定switchMap
是运行还是返回空数组。
inactiveItems$: Observable<any[]> = combineLatest(
this.store.select(fromAuth.getAuthState),
this.showInactiveItems$
).pipe(
map(([authState, showInactiveItems]: any) => {
if (authState?.roles?.isAgent === true && showInactiveItems === true) {
return authState.uid;
}
return null;
}),
switchMap(uid => this.getItems(uid))
);
private getItems(uid): Observable<any[]> {
if (!uid) {
return of([]);
}
return this.db.collection('items', ref =>
ref.where('agentId', '==', uid)
.where('active', '==', false)
).valueChanges({ idField: 'id' }).pipe(
catchError(err => of([]))
);
}
如果filter
中的条件匹配,则map
返回uid
,否则返回null
。
如果uid
是falsy,则switchMap
返回一个空数组,否则获取项。