在初始化应用程序时,我想已经加载了用户(假设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));
});
}
我正在将状态中的动作链接起来,我希望我的应用程序在继续执行该应用程序之前先完成整个动作链。
这可能还是我做错了方向?
答案 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
。