Angular 路由是否订阅了可观察的 RouteGuards returns?

Do Angular routes subscribe to the observable a RouteGuards returns?

我对 Angular 路由如何处理守卫 returns 的可观察对象感到有点困惑。守卫走以下路线:

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
      })
    )
  }
}

守卫 returns 一个可观察对象,如果值为 true 则将 this.sessionQuery.loggedIn$ 映射到 true,如果值为 false 则映射到 loginPage

但是,我希望路由守卫会订阅可观察对象:this.sessionQuery.loggedIn$ 可观察对象,以便在它重新发出时,重新评估路由守卫中的逻辑。

然而,测试似乎表明并非如此。如果我在应用程序的其他地方订阅了这个 observable,我可以看到它重新发出,但是我在上面的代码中输入的 console.log 调用不会触发。

我希望路由守卫在 loggedIn$ observable 发出 false.

时触发自动注销

如果路由没有订阅守卫,那么守卫首先返回一个 observable 有什么意义?我觉得我在这里缺少一些东西...

您必须实现“当 sessionQuery.loggedIn$ 在其他地方发出 false 时的登录路由逻辑,可能是在急切注入其父模块的服务中(以确保它已实例化)。

要检查 Angular 使用 returned Observable 做什么,您可以 return 以下内容。我的猜测是,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();
    };
});