调度动作时的 ngrx 路由

Jor*_*rdi 1 ngrx angular

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

有没有使用更优雅的方式来做到这一点。例如,

  1. 不使用对我的IStore.user字段的显式订阅?
  2. 'USER_LOGIN_SUCCESS'分派操作 ( )时,我是否可以直接导航到路线?
  3. 我可以将所有这些行为集中在一个注射剂中吗?

有任何想法吗?

max*_*992 5

是的,您可以以更优雅的方式执行此操作。
让我们一步一步地回顾它:)

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)