angular - Angular 路由是否订阅了 RouteGuards 返回的 observable?
问题描述
我对 Angular 路由如何处理守卫返回的 observables 感到有些困惑。采取以下路线守卫:
export class AuthenticationGuard implements CanActivate {
constructor(private sessionQuery: SessionQuery, private router: Router){}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
const loginPage = this.router.parseUrl('/login')
return this.sessionQuery.loggedIn$.pipe(
map((loggedIn: boolean): boolean | UrlTree => {
console.log('loggedIn emitted: ', loggedIn)
return loggedIn ? true : loginPage
})
)
}
}
守卫返回一个映射this.sessionQuery.loggedIn$
到true
iftrue
或loginPage
if的 observable false
。
但是,我希望路由守卫会订阅 observable: this.sessionQuery.loggedIn$
observable ,这样当它重新发出时,路由守卫中的逻辑会被重新评估。
然而,测试似乎表明它没有。如果我在应用程序的其他地方订阅这个 observable,我可以看到它重新发出,但console.log
我在上面代码中的调用不会触发。
我希望路由守卫在loggedIn$
observable 发出时触发自动注销false
。
如果路线没有订阅守卫,那么守卫首先返回一个可观察的有什么意义?我觉得我在这里缺少一些东西......
解决方案
您必须实现“在sessionQuery.loggedIn$
其他地方发出 false 时登录的路由”的逻辑,可能是在急切地注入其父模块的服务中(以确保它被实例化)。
要检查 Angular 对返回的 Observable 做了什么,您可以返回以下内容。我的猜测是,Angular 获得了第一个发出的值并取消订阅。
return new Observable<boolean | UrlTree>((subscriber) => {
const subscription = this.sessionQuery.loggedIn$.pipe(
map((loggedIn: boolean): boolean | UrlTree => {
console.log('loggedIn emitted: ', loggedIn)
return loggedIn ? true : loginPage
})
).subscribe(subscriber);
return () => {
// called when no subscriber is left
console.log('unsubscribed');
subscription.unsubsribe();
};
});