【问题标题】:Route guard method breaking routing路由守卫方法破坏路由
【发布时间】:2019-02-04 20:05:39
【问题描述】:

编辑:StackBlitz minimal repro 似乎有效,所以似乎还有其他问题..

Angular 6.1.3

我有一条需要根据参数slug 保护的路由。

{
  path: 'market/:slug',
  component: MarketComponent,
  canActivate: [RoleGuard],
},

RoleGuardcanActivate 方法:

canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | Promise<boolean> | boolean {
  const market$ = this.marketService.getBySlug(
    route.paramMap.get('slug')
  ); // returns an observable of the corresponding market object

  // Verify the user is authorized to see this market.
  return this.authService.isAuthorized(market);
}

authService.isAuthorized:

isAuthorized(market: Observable<Market>): Observable<boolean> {
  return combineLatest(this.user$, market).pipe(
    map(([user, market]) => {
      // Check roles of the user based on the market's configuration
      return true;
    })
  );
}

我已经删除了用户/市场逻辑,只是试图去除任何可能导致问题的东西,但是当我在canActivate 中返回上述方法时,路由停止。路线追踪:

Router Event: NavigationStart
NavigationStart(id: 2, url: '/market/sams-corner-store')
NavigationStart {id: 2, url: "/market/sams-corner-store", navigationTrigger: "imperative", restoredState: null}

Router Event: RoutesRecognized
RoutesRecognized(id: 2, url: '/market/sams-corner-store', urlAfterRedirects: '/market/sams-corner-store', state: Route(url:'', path:'') { Route(url:'market/sams-corner-store', path:'market/:slug') } )
RoutesRecognized {id: 2, url: "/market/sams-corner-store", urlAfterRedirects: "/market/sams-corner-store", state: RouterStateSnapshot}

Router Event: GuardsCheckStart
GuardsCheckStart(id: 2, url: '/market/sams-corner-store', urlAfterRedirects: '/market/sams-corner-store', state: Route(url:'', path:'') { Route(url:'market/sams-corner-store', path:'market/:slug') } )
GuardsCheckStart {id: 2, url: "/market/sams-corner-store", urlAfterRedirects: "/market/sams-corner-store", state: RouterStateSnapshot}

Router Event: ChildActivationStart
ChildActivationStart(path: '')
ChildActivationStart {snapshot: ActivatedRouteSnapshot}

Router Event: ActivationStart
ActivationStart(path: 'market/:slug')
ActivationStart {snapshot: ActivatedRouteSnapshot}

在正常路由期间,会触发更多路由器事件,但在这里它就停止了。我认为这与isAuthorized 没有发出任何东西有关,但我很难过。失败后,导航到任何地方都无济于事; URL 保持不变,控制台不会记录任何其他内容。

有时甚至不调用该方法,也不会在combineLatest/withLatestFrom 中调用console.log。

我尝试了 combineLatestwithLatestFrom 与一些运算符变体无济于事。

【问题讨论】:

    标签: angular rxjs angular2-routing


    【解决方案1】:

    canActivate 守卫将订阅返回的 Observable 并等待该 Observable 完成,直到那时不会处理其他路由器事件。
    first()(Rx 运算符)添加到 user$ 和 market$ Observable。
    PS 而不是combineLatest 使用forkJoin

    【讨论】:

    • 感谢您对路由器事件的确认。我认为在我的实现中有些东西有点不对劲,但在尝试将问题归零时,这有帮助。
    【解决方案2】:

    你做对了,但是守卫需要 observable 来完成。 所以你一直在等待它。

    尝试做

    return this.authService.isAuthorized(market).pipe(
        take(1)
    );
    

    这将采用第一个结果并完成,这应该可以解决您的问题。

    【讨论】:

    • 就像上面的评论一样,我的代码有些问题,但在其他测试中take 提供帮助,谢谢!
    猜你喜欢
    • 2018-12-04
    • 2017-10-01
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 2016-10-18
    • 2019-10-21
    • 2021-06-01
    • 2018-01-10
    相关资源
    最近更新 更多