Angular 试图理解CanActivate和CanActivateChild之间的区别

Angular 试图理解CanActivate和CanActivateChild之间的区别,angular,angular2-guards,Angular,Angular2 Guards,所以,我试图通过使用警卫来保护通往几条路线的通道。我正在使用以下方法来实现此目的: const adminRoutes : Routes = [ { path: 'admin', component: AdminComponent, canActivate: [ AuthGuardService ], children : [ { path: '', canActivateChild: [ AuthGuardServ

所以,我试图通过使用警卫来保护通往几条路线的通道。我正在使用以下方法来实现此目的:

const adminRoutes : Routes = [
  {
    path: 'admin',
    component: AdminComponent,
    canActivate: [ AuthGuardService ],
    children : [
      {
        path: '',
        canActivateChild: [ AuthGuardService ],
        children: [
          { path: 'edit', component: DashboardComponent},
          { path: '', component: DashboardComponent}
        ]
      }
    ]
  }
];
下面我们来看一下
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
  }

}
当我尝试仅使用
canActivate
访问“/admin”和“/admin/edit”(注释为
canActivateChild
)时,控制台显示

Guarding...
当我移除
canActivate
并将
canActivateChild
带回时,控制台显示

Guarding children...
当我保留这两个选项时,它会返回显示
保护…
。 因此,我的问题是,当
canActivate
同时保护根元素和子元素时,使用
canActivateChild
的目的是什么


PS:我知道
canActivateChild
在子路由被激活之前运行。但这有什么好处呢?仅保留其中一个组件还不够吗?

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

示例:您可能遇到这样的情况:用户必须经过身份验证才能导航到根组件,但必须具有访问子组件的权限“x”。在这样的情况下,
canActivateChild
省去了为每个子项添加
canActivate
防护的大量输入

编辑:

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

  {
    path: 'admin',
    component: AdminComponent,
    canActivate: [ AuthGuardService ],
    children : [
      {
        path: '', component: ...,
      },
      {
        path: 'manage-users', component: ...,
      },
      {
        path: 'manage-roles', component: ...,
      }
    ]
  }
这需要从上到下进行保护。禁止未经授权访问任何路由,包括根路由和子路由。在这种情况下,根级别的
canActivate
可以很好地保护所有内容

但您也可能有这样的情况,即您有一个功能模块,其中只需要保护某些儿童:

  {
    path: 'featureA',
    component: ...,
    canActivateChild: [ AuthGuardService ],
    children : [
      {
        path: 'manage-feature', component: ...,
      },
      {
        path: 'manage-members', component: ...,
      }
    ],
    {path: 'featureB', component: ...}
  }
在这种情况下,可能所有用户都需要访问根组件“FeatureUrea”和“featureB”,但只有某些用户需要能够导航到“FeatureUrea”的子路由。在这种情况下,更容易在根级别使用一个保护来保护子级,而不是根本身。另一种方法是在每个子路由上设置
canActivate
guards,这可能会变得单调乏味


这实际上完全取决于您的需求,但在我看来,
canActivate
canActivateChild
这两个选项都很好,
CanActivate
用于限制从特定路径和所有子路径的访问,
CanActivateChild
用于限制对
CanActivate
路径内特定组的访问

例如:

{
  path: 'admin',
  component: AdminComponent,
  canActivate: [AuthGuardService],
  children : [
    {
      path: 'books', component: ...,
    },
    {
      path: 'authors', component: ...,
    },
    {
      path: 'payments',
      canActivateChild: [AuthGuardService],
      children: [
        {
          path: 'list', component: ...
        },
        {
          path: 'list/:id', component: ...
        }
      ]
    }
  ]
}

由于需要两种类型的验证,因此不能有两种
canActivate
方法,因此需要
canActivateChild
来检查
canActivate
路径中的权限。显然,您可以创建不同的保护服务(
AuthGuardForChildrenRoutes
)并仍然使用
canActivate
方法,但这不是重点。

在您的示例中,您在canActivateChild中调用了canActivate,因此当您在子路由之间遍历时,会调用这两个保护。如果在两个保护内部有不同的身份验证逻辑,那么在子路由之间遍历时,您的canActivate保护将不会执行

高级文书主任。 激活 激活儿童 1. 它阻止对父路由的访问,父路由还包括对所有子路由的访问 我们可以访问父路由,但如果需要,我们可以选择使用canActivateChild阻止特定的子路由 2. 是的,您可以通过将CanActivate应用于所有子路由来实现CanActivateChild行为 只需在父路由中添加CanActivateChild即可节省大量时间,而且更方便
那么我们就不能用canActivate而不是canActivateChild吗?也许,这取决于您的要求。我上面给出的例子可能有点做作<代码>canActivateChild在激活每个子路由之前运行。您确实可以使用
canActivate
保护根组件和所有子组件,但您可能有一些子组件,某些用户在需要查看根组件时不需要查看。例如,您可以将一些管理组件添加到功能模块中,大多数或所有用户都需要访问该功能模块的根目录,但不一定是某些路由的子目录。