结合 ngxs 和 rxjs 创建路由守卫
Combining ngxs and rxjs to create an route guard
因为我对 RXJS 和 NGXS 还很陌生,所以请多多包涵。我正在尝试使用这两个库设置 authguard。
所以开始:
./AuthState.ts
@Injectable()
export class AuthState {
@Selector()
static isAuthenticated(state: AuthStateModel): boolean {
return !!state.token;
}
@Action(Login)
login(ctx: StateContext<AuthStateModel>, action: Login) {
return this.authService.login(action.payload).pipe(
tap((result: { token: string }) => {
ctx.patchState({
token: result.token,
username: action.payload.username
});
})
);
}
// ... left out for brevity
现在我已经看到了几个使用 .take(1)
方法的可观察对象示例。在 NXJS 文档中,它指出 the store select 有一个名为 selectOnce
的函数。基本上 select().pipe(take(1))
.
我怎样才能将其付诸实践?
./auth.guard.ts
canActivate(_, state: RouterStateSnapshot) {
// I'd like to do an early return when the user is not authenticated
// And I was assuming since the `isAuthenticated` method in AuthState returns a boolean this would work... (but it doesn't)
if (!this.store.selectOnce((authState) => authState.isAuthenticated)) {
this.router.navigate(
['auth/login'],
{ queryParams: { returnUrl: state.url } }
);
return false;
}
// otherwise all is good...
return true;
}
但这不起作用。所以我可能弄错了其中一个概念。
好的。我有点倒退了:
canActivate(_, state: RouterStateSnapshot) {
const isAuthenticated = this.store.selectSnapshot(AuthState.isAuthenticated);
if (!isAuthenticated) {
this.router.navigate(['auth/login'], { queryParams: { returnUrl: state.url } });
return false;
}
return true;
}
事实证明,您应该使用 selectSnapshot 从 class AuthState 中获取 属性 isAuthenticated。 (很明显 described in the documentation)
另见 snapshot selects。
因为我对 RXJS 和 NGXS 还很陌生,所以请多多包涵。我正在尝试使用这两个库设置 authguard。
所以开始:
./AuthState.ts
@Injectable()
export class AuthState {
@Selector()
static isAuthenticated(state: AuthStateModel): boolean {
return !!state.token;
}
@Action(Login)
login(ctx: StateContext<AuthStateModel>, action: Login) {
return this.authService.login(action.payload).pipe(
tap((result: { token: string }) => {
ctx.patchState({
token: result.token,
username: action.payload.username
});
})
);
}
// ... left out for brevity
现在我已经看到了几个使用 .take(1)
方法的可观察对象示例。在 NXJS 文档中,它指出 the store select 有一个名为 selectOnce
的函数。基本上 select().pipe(take(1))
.
我怎样才能将其付诸实践?
./auth.guard.ts
canActivate(_, state: RouterStateSnapshot) {
// I'd like to do an early return when the user is not authenticated
// And I was assuming since the `isAuthenticated` method in AuthState returns a boolean this would work... (but it doesn't)
if (!this.store.selectOnce((authState) => authState.isAuthenticated)) {
this.router.navigate(
['auth/login'],
{ queryParams: { returnUrl: state.url } }
);
return false;
}
// otherwise all is good...
return true;
}
但这不起作用。所以我可能弄错了其中一个概念。
好的。我有点倒退了:
canActivate(_, state: RouterStateSnapshot) {
const isAuthenticated = this.store.selectSnapshot(AuthState.isAuthenticated);
if (!isAuthenticated) {
this.router.navigate(['auth/login'], { queryParams: { returnUrl: state.url } });
return false;
}
return true;
}
事实证明,您应该使用 selectSnapshot 从 class AuthState 中获取 属性 isAuthenticated。 (很明显 described in the documentation)
另见 snapshot selects。