Ngxs-承诺采取一系列行动?

时间:2018-06-20 14:57:00

标签: angular ngxs

在初始化应用程序时,我想已经加载了用户(假设localStorage中有一个令牌)。我遵循了本指南https://www.intertech.com/Blog/angular-4-tutorial-run-code-during-app-initialization/,但是现在我迷失了如何将其与ngxs结合在一起,尤其是在我的设置中。

应用初始化时将调用此函数:

  initializeApp() {
    const token = localStorage.getItem('token');
    if (token) {
      this.store.dispatch(new CheckSession(token));

   //hold the user
    }
  }

动作

@Action(CheckSession)
checkSession(sc: StateContext<SessionStateModel>, { payload }: CheckSession) {
sc.patchState({
  isLoading: true,
  token: payload
});

this.sessionService.checkSession()
  .subscribe(response => {
    sc.dispatch(new CheckSessionSuccess(response));
  }, error => {
    sc.dispatch(new CheckSessionFailed(error));
  });
}

我正在将状态中的动作链接起来,我希望我的应用程序在继续执行该应用程序之前先完成整个动作链。

这可能还是我做错了方向?

2 个答案:

答案 0 :(得分:1)

基于代码执行的异步特性,请改用这种方法:

  • 使用“正在加载”路线/页面/组件开始您的应用,该路线/页面/组件仅显示某种加载指示器。
  • 订阅ofActionSuccessful()中的CheckSessionXxx,这将相应地更改路由/页面/组件。
  • 发送CheckSession。此操作的结果将由上一步处理。
  • 如果没有令牌,请相应地更改路线/页面/组件。

该想法是避免在呈现UI之前“等待过程完成”。相反,请始终根据当前状态呈现UI(例如,正在加载...)。由于异步操作会导致应用程序状态发生变化,因此请及时更新UI

这不是编码解决方案,而是建议进行设计/思想更改-否则,您将在许多情况下尝试“等待”(恕我直言,就像与“系统”作战)。希望这会有所帮助。

答案 1 :(得分:0)

我认为您应该使用AuthGuard来实现这一点,

@Injectable()
export class AuthGuard implements CanActivate {
    constructor(private _auth: AuthService, private _store: Store) {}

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        return this._isAuthenticated$.pipe(
            map(a => {
                if (a) {
                    return true;
                }
                this._store.dispatch(new CheckSession(state.url));
                return false;
            })
        );
    }

    @Select(AuthState.isAuthenticated)
    private _isAuthenticated$: Observable<boolean>;
}

,然后在实际调用该组件之前使用它。您可以检查以下示例 repository