试图了解CanActivate和CanActivateChild之间的差异

You*_*esM 9 angular2-guards angular

所以,我试图通过使用警卫来保护对多条路线的访问.我正在使用以下路由来执行此操作:

const adminRoutes : Routes = [
  {
    path: 'admin',
    component: AdminComponent,
    canActivate: [ AuthGuardService ],
    children : [
      {
        path: '',
        canActivateChild: [ AuthGuardService ],
        children: [
          { path: 'edit', component: DashboardComponent},
          { path: '', component: DashboardComponent}
        ]
      }
    ]
  }
];
Run Code Online (Sandbox Code Playgroud)

这是一个AuthGuardService看起来像什么的看

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

@Injectable()
export class AuthGuardService implements CanActivate{

  constructor(private router: Router) { }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot){
    console.log("Guarding...");
    return this.sessionValid();
  }

  canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot){
    console.log("Guarding children...");
    return this.canActivate(route, state);
  }

  sessionValid() : boolean {
    //tests
  }

}
Run Code Online (Sandbox Code Playgroud)

当我尝试访问'/ admin'和'/ admin/edit'时,canActivate仅显示(canActivateChild已注释)控制台显示

Guarding...
Run Code Online (Sandbox Code Playgroud)

当我删除canActivatecanActivateChild带回控制台显示

Guarding children...
Run Code Online (Sandbox Code Playgroud)

当我保留两者时,它会回到显示状态Guarding....所以,我的问题是什么canActivateChild时候canActivate保护根元素和孩子们的目的是什么?

PS:我得到它canActivateChild在子路由被激活之前运行.但那有什么好处呢?是不是只保留其中一个?

Tyl*_*ngs 19

两者都很重要,因为您可能有不同的要求,用户可以访问根组件,但可能不满足子组件的条件.

示例:您可能遇到必须通过身份验证才能导航到根组件的情况,但必须具有权限"x"才能访问子组件.在这种情况下,canActivateChild由于必须canActivate为每个孩子添加警卫,可以节省大量的打字.

编辑:

例如,您可能有一个管理模块,其中所有路由都需要防止未经授权的进入:

  {
    path: 'admin',
    component: AdminComponent,
    canActivate: [ AuthGuardService ],
    children : [
      {
        path: '', component: ...,
      },
      {
        path: 'manage-users', component: ...,
      },
      {
        path: 'manage-roles', component: ...,
      }
    ]
  }
Run Code Online (Sandbox Code Playgroud)

这需要从上到下保护.未经授权访问任何路由,包括root和children.在这种情况下canActivate,根级别可以很好地保护一切.

但是,您可能还有一些功能模块,其中只需要保护某些孩子:

  {
    path: 'featureA',
    component: ...,
    canActivateChild: [ AuthGuardService ],
    children : [
      {
        path: 'manage-feature', component: ...,
      },
      {
        path: 'manage-members', component: ...,
      }
    ],
    {path: 'featureB', component: ...}
  }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,也许所有用户都需要访问根组件的featureA'和'featureB',但只有某些用户需要能够导航到'featureA'的子路由.在这种情况下,更容易在根级别使用一个防护装置来保护儿童,而不是根本身.另一种方法是canActivate在每条儿童路线上放置警卫,这可能会变得乏味.

这真的一切都取决于你的要求,但它可以是不错的选择都canActivatecanActivateChild.

  • 也许,这取决于您的要求.我上面给出的例子可能有点太做作了.在每个子路由被激活之前运行`canActivateChild`.您确实可以使用`canActivate`保护所有子项的根组件,但是您可能有子项,某些用户不需要查看他们何时需要能够查看根组件.例如,您可以将一些Admin组件添加到Feature模块中,大多数或所有用户需要访问它们的根,但不一定是某些路由的子节点. (3认同)