调度操作时的ngrx路由

时间:2017-03-13 10:08:47

标签: angular ngrx

我使用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路线。

是否可以使用优雅的方式来做到这一点。例如,

  1. 没有明确订阅我的IStore.user字段?
  2. 在调度操作('USER_LOGIN_SUCCESS')时,我可以直接导航到路线吗?
  3. 我可以将所有这些行为集中在一个注射剂中吗?
  4. 有什么想法吗?

2 个答案:

答案 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​​}}

中应用您的逻辑

在订阅之前使用subscribedo来处理您的逻辑 - 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']);
    }
);

然后你不需要订阅中的条件。