首页 > 解决方案 > ngrxOnRunEffects 方法停止效果调度其他效果

问题描述

我所做的

我有一个 Angular 应用程序,我正在实施 NGRX 10 以在登录后管理帐户信息。所以我做了登录操作,当用户登录或加载应用程序并从服务器加载会话时调用。

这就是我实现登录效果的方式

  LogIn$ = createEffect(
    () => this.actions$.pipe(
      ofType(UserActions.logInUser),
      switchMap(( action ) => {
        console.log('login');
        return this.backendService.login(action.credentials, action.remember).pipe(
          mergeMap(data => [
            UserActions.logInUserSuccess(data),
            UserActions.saveOAuthInCookie(data)
          ]),
          catchError( error => of(UserActions.loginUserFail(error)))
        );
      })
    ), { dispatch: true }
  );

当我访问先前打开的会话的页面的受限部分时,我需要确保已从服务器加载帐户信息。

然后我尝试在我的应用程序模块中实现类似以下代码的内容:

export function initApplication(store: Store<IState>): Function {
    return () => new Promise((resolve, reject) => {
        store.dispatch(StartAppInitializer({}));
        store.dispatch(loadOAuthFromCookie({}));
        store.select((state) => state.user)
          .pipe(
            filter(user => ((user.oAuthToken && user.oAuthToken.length > 0 &&
              (user.account && user.account.email && user.account.email.length > 0) ) ||
              (!user.oAuthToken || user.oAuthToken.length === 0))),
            take(1)
       ).subscribe((account) => {
           store.dispatch(FinishAppInitializer({}));
           resolve(false);
       });
  });
}

在我的效果类实现OnRunEffects和这段代码中:

  ngrxOnRunEffects(resolvedEffects$: Observable<EffectNotification>): Observable<EffectNotification> {
      return this.actions$.pipe(
        ofType('LOGGED_IN'),
        exhaustMap(() =>
          resolvedEffects$.pipe(
            takeUntil(this.actions$.pipe(ofType('LOGGED_OUT')))
          )
        )
      );
    }

这改变了它假设要等到应用程序调用FinishAppInitializer

我想要的是

我想停止应用程序加载,直到 NGRX 从服务器获取帐户信息

我得到了什么

在我的效果类上实现 ngrxOnRunEffects 之前,我的效果可以工作,但是在我的效果类上实现 ngrxOnRunEffects 之后,其他效果停止调度其他动作。

这是一些参考我登录时发生的事情的图像:

在我实施 ngrxOnRunEffects 之前的图像

实施 ngrxOnRunEffects 后的图像

我找到的解决方案

首先我改变了这个:

    {
      provide: APP_INITIALIZER,
      useFactory: () => initApplication,
      multi: true,
      deps: [[new Inject(Store)]]
    },

为了这:

    {
      provide: APP_INITIALIZER,
      useFactory: initApplication,
      multi: true,
      deps: [[new Inject(Store)]]
    },

此更改会导致应用程序停止,直到履行承诺。

其次,我将 ngrxOnRunEffects 方法移动到另一个类,这解决了没有调用其他效果的问题。

标签: angularngrxngrx-effects

解决方案


推荐阅读