【问题标题】:Guard always redirects to the default routeGuard 总是重定向到默认路由
【发布时间】:2017-06-16 18:47:10
【问题描述】:

我有一个检查用户会话的警卫。 我正在从一个承诺中创建一个可观察对象并返回该可观察对象。

不幸的是,路由器总是在刷新时将我重定向到主页。 我想这与 observable 有关系,因为当我简单地导航时,它会输入 if 并返回 'Observalbe.of(true)',这很有效。

@Injectable()
export default class SessionGuard implements CanActivate {

  constructor(private authService: AuthService) {}

  public canActivate(): Observable<boolean> | Promise<boolean> | boolean {
    if (this.authService.hasSessionChecked) {
      return Observable.of(true).take(1);
    }

    const obs = Observable.fromPromise(this.authService.getSession());
    return obs.map((session) => {
      this.authService.setUserSession(session);
      return true;
    }).take(1);
  }
}

我尝试用“return true”替换 observable,一切正常。

有什么想法吗?谢谢!

【问题讨论】:

    标签: angular observable guard canactivate


    【解决方案1】:

    它不起作用,因为canActivate 应该返回一个布尔值。

    为什么要使用 Observable ?

    【讨论】:

    • 这不是真的,接口中canActivate的定义允许3种返回类型:export interface CanActivate { canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable |承诺 |布尔值; }
    • angular.io/api/router/CanActivate 第一个示例的第 15 行。
    • 就在它下面的那一行,你可以看到它从权限返回canActivate函数。看看这个函数返回什么。
    • 在这个例子中,它返回一个布尔值。但是,正如您在第 15 行看到的那样,它可以返回解析为布尔值或布尔值的 promise 或 observable。
    • 我会请你考虑一下。如果这个函数只返回另一个函数的结果,那么它可以返回什么?
    【解决方案2】:

    首先canActivate的定义如下:

    export interface CanActivate {
        canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean;
    }
    

    所以你应该在函数中添加参数。

    第二,如果你要返回一个observable并且只返回一个observable,那么将返回类型改为just observable。如果你想要混合,那么你可以留下多个返回类型。

    第三,去掉 take() 操作符,将守卫重构为如下所示:

    @Injectable()
    export default class SessionGuard implements CanActivate {
    
      constructor(private authService: AuthService) {}
    
      public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
        if (this.authService.hasSessionChecked) {
          return true;
        }
        const obs = Observable.fromPromise(this.authService.getSession());
        return obs.map(session => {
          this.authService.setUserSession(session);
          return true;
        });
      }
    }
    

    【讨论】:

    • 我得到了同样的结果
    【解决方案3】:

    正如@trichetriche 所建议的,我已将可观察对象替换为承诺并返回。

    现在效果很好。

    return this.authService.getSession().then(
      data => {
        this.authService.setUserSession(data);
        return true;
      },
      err => false,
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-20
      • 1970-01-01
      • 2015-09-30
      • 2018-02-14
      • 1970-01-01
      • 2012-04-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多