是的,你可以用更优雅的方式做到这一点。
让我们一步一步地回顾它:)
1) 使用 rxjs 中的 filter 而不是 if 语句
this.userSub = this
.user$
.filter((user: IUser) => user.id !== null)
.subscribe((user: IUser) => this.router.navigate(['/app']));
2) 避免逐个处理订阅
(Ben Lesh 在Medium 上发表了一篇很棒的文章)
private componentDestroyed$: new Subject<void>();
ngOnInit() {
this
.user$
.filter((user: IUser) => user.id !== null)
.takeUntil(this.componentDestroyed$)
.subscribe(_ => this.router.navigate(['/app']));
}
ngOnDestroy() {
this.componentDestroyed$.next();
this.componentDestroyed$.complete();
}
3) 不要在subscribe中应用你的逻辑
在订阅之前使用do 或map 处理您的逻辑。
- do 如果您只是需要做某事
- map如果你想返回结果
this
.user$
.filter((user: IUser) => user.id !== null)
.takeUntil(this.componentDestroyed$)
.do(_ => this.router.navigate(['/app']))
.subscribe();
(CF 下一部分“为什么”)
4) 如果您想重用或导出某些逻辑,请使用“选择器”
如果我必须对您的代码进行一些猜测,我想您的 user$ 是当前用户。那个连接对吗?而且您可能必须将所有代码复制到应用的其他部分才能再次找到该用户。
这是“selector”的一个很好的用例。
(我在这里导出了 2 个函数,所以这段代码可以对 AOT 友好)。 p>
export function _getCurrentUser(store: Store<any>) {
return store$
.select(state => state.user)
.filter((user: IUser) => user.id !== null);
}
然后在你的组件中:
this
.store$
.let(getCurrentUser)
.takeUntil(this.componentDestroyed$)
.do(_ => this.router.navigate(['/app']))
.subscribe();
我们终于有了
user.selector.ts:
export function getCurrentUser(store: Store<any>) {
return store$
.select(state => state.user)
.filter((user: IUser) => user.id !== null);
}
component:
private componentDestroyed$: new Subject<void>();
ngOnInit() {
this
.store$
.let(getCurrentUser)
.takeUntil(this.componentDestroyed$)
.do(_ => this.router.navigate(['/app']))
.subscribe();
}
ngOnDestroyed() {
this.componentDestroyed$.next();
this.componentDestroyed$.complete();
}