在使用@ngrx/effect
的Angular项目中,使用withLatestFrom
rxjs运算符可以观察到流。
这是我们可观察到的效果流:
@Effect()
handleUsersData$ = this.actions$
.pipe(
ofType(HANDLE_USER_DATA),
withLatestFrom(
this.store.pipe(select(getCurrentUserId)),
this.store.pipe(select(getUserEntities)),
),
tap(([action, currentUserId, users]) => console.log(([action, currentUserId, users]))),
switchMap(([action, currentUserId, users]) => {
const dispatchedActions: Action[] = [];
if (currentUserId) {
dispatchedActions.push(new SetCurrentUser());
} else {
dispatchedActions.push(new SomeAction());
dispatchedActions.push(new ClearUsers());
}
return dispatchedActions;
})
);
我们使用的选择器之一是:
export const getCurrentUserId = createSelector(
getUserEntities,
getRouterStateUrl,
(users: Dictionary<User>, router: RouterStateUrl) => {
return router.params && users[router.params.userId] || null;
}
);
定义userId
后,将正确分派动作。 console.log
显示用户ID和用户实体。
但是,如果userId
不在路由器参数中,那么选择器将返回null
,并且可观察到的流将永远不会滴答。 console.log
中的tap
不返回任何内容
为什么withLatestFrom
似乎忽略了null
的值,但如果此值是选择器的结果,它只是不打勾?在我们的上下文中,这是一个有效值。
即使getCurrentUserId
选择器中的值为空,如何确保可观察的流滴答作响?
答案 0 :(得分:3)
您似乎想改用combineLatest
。
withLatestFrom
不会忽略null
。这是常规值。但是,withLatestFrom
仅对直接来源的排放做出反应。来自this.actions$.pipe(ofType(HANDLE_USER_DATA))
。它也保留了其他来源的排放物,但仅将其保留在内部缓冲区中,而对它们没有反应。
另一方面,combineLatest
将从每个源发出的所有发射都可观察到,它们都发出至少一项之后(如果要确保所有源至少发出一个,请查看startWith
)一次)。