我正在使用 ngrx 来存储我的用户状态。对于用户状态,我指的是IUser具有一些用户属性的类对象。
我已经设置了几个动作 ( 'USER_LOGIN', 'USER_LOGIN_SUCCESS' and 'USER_LOGJN_FAILED')。
目前,当USER_LOGIN_SUCCESS调度an 时,reducer 将新用户信息分配给我的IStore.userngrx store 字段。当它改变时:
this.user$ = this.store$.select(state => state.user);
this.userSub = this.user$.subscribe(
(user: IUser) => {
if (user.id != null)
this.router.navigate(['/app']);
}
);
Run Code Online (Sandbox Code Playgroud)
如您所见,我只检查我更改的用户的状态是否是user.id != null,然后导航到我的/app路线。
有没有使用更优雅的方式来做到这一点。例如,
IStore.user字段的显式订阅?'USER_LOGIN_SUCCESS'分派操作 ( )时,我是否可以直接导航到路线?有任何想法吗?
是的,您可以以更优雅的方式执行此操作。
让我们一步一步地回顾它:)
1) 使用filterfrom rxjs 而不是if语句
this.userSub = this
.user$
.filter((user: IUser) => user.id !== null)
.subscribe((user: IUser) => this.router.navigate(['/app']));
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
3)不要在里面应用你的逻辑 subscribe
在订阅之前使用 ado或 amap来处理您的逻辑。
-do如果您只是需要做某事
-map如果您想返回结果
this
.user$
.filter((user: IUser) => user.id !== null)
.takeUntil(this.componentDestroyed$)
.do(_ => this.router.navigate(['/app']))
.subscribe();
Run Code Online (Sandbox Code Playgroud)
(CF 下一部分为“为什么”)
4) 如果要重用或导出某些逻辑,请使用“选择器”
如果我不得不对您的代码进行一些猜测,我想您的 user$ 是当前用户。一个连接对吗?您可能需要在应用的其他部分复制所有代码才能再次找到该用户。
这是“选择器”的一个很好的用例。
(我在这里导出了 2 个函数,所以这个代码可以是 AOT 友好的)。
export function _getCurrentUser(store: Store<any>) {
return store$
.select(state => state.user)
.filter((user: IUser) => user.id !== null);
}
Run Code Online (Sandbox Code Playgroud)
然后在您的组件中:
this
.store$
.let(getCurrentUser)
.takeUntil(this.componentDestroyed$)
.do(_ => this.router.navigate(['/app']))
.subscribe();
Run Code Online (Sandbox Code Playgroud)
最后我们有
一个user.selector.ts:
export function getCurrentUser(store: Store<any>) {
return store$
.select(state => state.user)
.filter((user: IUser) => user.id !== null);
}
Run Code Online (Sandbox Code Playgroud)
一个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();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1407 次 |
| 最近记录: |