路由保护方法破坏路由

时间:2018-08-29 23:55:29

标签: angular rxjs angular2-routing

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

角度6.1.3

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

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

RoleGuard canActivate方法:

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的某些操作符变体,但无济于事。

2 个答案:

答案 0 :(得分:1)

您做对了,但是守卫需要观察员来完成。 因此,您不得不等待它。

尝试做

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

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

答案 1 :(得分:1)

canActivate守卫将订阅返回的Observable,并等待该Observable完成,直到那一刻,其他路由器事件都将不被处理。
first()(Rx运算符)添加到可观察的用户$和市场$。
PS代替combineLatest使用forkJoin