我使用ngrx来存储我的用户状态。对于用户状态,我指的是具有一些用户属性的IUser
类对象。
我已设置多项操作('USER_LOGIN', 'USER_LOGIN_SUCCESS' and 'USER_LOGJN_FAILED'
)。
目前,当调度USER_LOGIN_SUCCESS
时,reducer会将新用户信息分配给我的IStore.user
ngrx商店字段。当它改变时:
this.user$ = this.store$.select(state => state.user);
this.userSub = this.user$.subscribe(
(user: IUser) => {
if (user.id != null)
this.router.navigate(['/app']);
}
);
正如您所看到的,我只检查我更改的用户的状态是user.id != null
,然后我导航到我的/app
路线。
是否可以使用优雅的方式来做到这一点。例如,
IStore.user
字段?'USER_LOGIN_SUCCESS'
)时,我可以直接导航到路线吗?有什么想法吗?
答案 0 :(得分:4)
是的,你可以用更优雅的方式做到这一点 让我们一步一步地审查它:)
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)请勿在{{1}}
中应用您的逻辑在订阅之前使用subscribe
或do
来处理您的逻辑
- map
如果您只是需要做某事
- do
如果要返回结果
map
(CF的下一部分为&#34;为什么&#34;)
4)使用&#34;选择器&#34;如果你想重新使用或导出一些逻辑
如果我必须对您的代码进行一些猜测,我认为您的用户$是当前用户。一个连接对吗?您可能需要复制应用程序其他部分的所有代码才能再次找到该用户。
这是&#34; selector &#34;的良好用例。 (我在这里导出了2个函数,所以这段代码可以是AOT友好的。)
this
.user$
.filter((user: IUser) => user.id !== null)
.takeUntil(this.componentDestroyed$)
.do(_ => this.router.navigate(['/app']))
.subscribe();
然后在你的组件中:
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
答案 1 :(得分:0)
您可以做的一件事就是在您的订阅上使用.skipUntil运算符,如下所示;
this.user$ = this.store$.select(state => state.user);
this.user$.skipUntil( user => user.id );
this.userSub = this.user$.subscribe(
(user: IUser) => {
this.router.navigate(['/app']);
}
);
然后你不需要订阅中的条件。