Angular 2 Router Guards命令

Mah*_*esh 8 angular2-routing angular

可以在阵列中定义Angular 2路由器防护装置.例如:

<code>
 canActivate: ['CanAlwaysActivateGuard','AuthGuard']
</code>
Run Code Online (Sandbox Code Playgroud)

以下是我的问题:

  1. 两个警卫的执行顺序是什么.
  2. 如果我想仅在CanAlwaysActivateGuard返回true时才执行AuthGuard,那么这是可能的.

小智 9

我遇到了这个问题,并在寻找答案时遇到了您的帖子。没有找到——今天有一些时间——我想出了一个我认为你可能感兴趣的解决方案。我创建了一个“CompositeRouteGuard”:

import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import {Injectable, Injector} from '@angular/core';
import { Observable } from "rxjs";

@Injectable()
export class CompositeRouteGuard implements CanActivate {

  constructor(  protected router: Router,
                protected injector: Injector ) {
  }

  canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable<boolean> {
    var compositeCanActivateObservable: Observable<boolean> = Observable.of(true);

    let routeGuards = route.data.routeGuards;

    if(routeGuards){
      for( var i = 0; i < routeGuards.length; i++ ){
        let routeGuard = this.injector.get(routeGuards[i]);
        let canActivateObservable = routeGuard.canActivate(route, state);
        compositeCanActivateObservable = compositeCanActivateObservable.flatMap( (bool) => {
          if(!bool){
            return Observable.of(false);
          }
          else{
            return canActivateObservable;
          }
        });
      }
    }

    return compositeCanActivateObservable;
  }
}
Run Code Online (Sandbox Code Playgroud)

这需要在你的 routes.ts 中进行一些额外的配置。您需要将“routeGuards”数组添加到路由的数据元素中。

const routes: Routes = [
  {
    path: '...',
    component: AComponent,
    data: { routeGuards: [ FooRouteGuard, BarRouteGuard, BazRouteGuard ] },
    canActivate: [ CompositeRouteGuard ]
  },
...
Run Code Online (Sandbox Code Playgroud)

我只关心 canActivate 操作,但是您应该能够轻松扩展它,如果需要,可以说“canDeactivate”(例如)。

现在,我的路线守卫使用“和”语义“按顺序”运行(所有路线都必须成功才能激活路线)。


Max*_*kyi 8

两个警卫的执行顺序是什么.

它们将同步运行而无需相互等待.

如果我想仅在CanAlwaysActivateGuard返回true时才执行AuthGuard,那么这是可能的.

不,目前的实施是不可能的.作为一种解决方法,您可以创建一个包装警卫,以便按顺序运行您的警卫.

另请参阅如何在Angular中等待守卫.


Lar*_*sen 5

如果嵌套它们,您可以决定它们的顺序:

import { Routes } from '@angular/router';

const routes: Routes = [
  {
    path: '',
    canActivate: [CanAlwaysActivateGuard],
    children: [
      {
        path: '',
        canActivate: [AuthGuard],
        children: [
          // (...)
        ],
      }
    ],
  }
];
Run Code Online (Sandbox Code Playgroud)

外部路由防护先于任何内部路由防护进行评估。