CanActivate vs. CanActivateChild with component-less routes

时间:2016-10-20 19:53:23

标签: angular angular2-routing

The angular2 documentation about Route Guards left me unclear about when it is appropriate to use a CanActivate guards vs. a CanActivateChild guard in combination with component-less routes.

TL;DR: what's the point in having canActivateChild when I can use a component-less routes with canActivate to achieve the same effect?

Long version:

We can have multiple guards at every level of a routing hierarchy. The router checks the CanDeactivate and CanActivateChild guards first, from deepest child route to the top. Then it checks the CanActivate guards from the top down to the deepest child route.

I get that CanActivateChild is checked bottom up and CanActivate is checked top down. What doesn't make sense to me is the following example given in the docs:

@NgModule({    
  imports: [
    RouterModule.forChild([
      {
        path: 'admin',
        component: AdminComponent,
        canActivate: [AuthGuard],
        children: [
          {
            path: '',
            canActivateChild: [AuthGuard],
            children: [
              { path: 'crises', component: ManageCrisesComponent },
              { path: 'heroes', component: ManageHeroesComponent },
              { path: '', component: AdminDashboardComponent }
            ]
          }
        ]
      }
    ])
  ],
  exports: [
    RouterModule
  ]
})
export class AdminRoutingModule {}

So the admin path has a component-less route:

Looking at our child route under the AdminComponent, we have a route with a path and a children property but it's not using a component. We haven't made a mistake in our configuration, because we can use a component-less route.

Why is the code in this case inserting the AuthGuard in the child and in the root component (path admin)? Wouldn't is suffice to guard at the root?

I have created a plunkr based on the sample that removes the canActivateChild: [AuthGuard] and adds a logout button on the AdminDashboard. Sure enough, the canActivate of the parent route still guards, so what's the point in having canActivateChild when I can use component-less routes with canActivate?

6 个答案:

答案 0 :(得分:42)

From the docs:

  

当我们了解如何使用CanActivate保护路线时,我们还可以使用CanActivateChild防护来保护儿童路线。 CanActivateChild防护与CanActivate后卫的工作方式类似,但不同之处在于它在每个子路由被激活之前运行。我们保护我们的管理功能模块免受未经授权的访问,但我们也可以保护我们的功能模块中的子路由

这是一个实际的例子:

  1. 导航至/admin
  2. canActivate已选中
  3. 您在/admin路线的子项之间导航,但canActivate未被调用,因为它保护/admin
  4. 只要在其定义的路线的子项之间进行更改,就会调用
  5. canActivateChild
  6. 我希望这对您有所帮助,如果仍然不清楚,您可以通过添加警卫调试它们来检查特定功能。

答案 1 :(得分:6)

在现实世界中,我觉得为父母及其所有孩子使用相同的守卫是多余的。

更好的例子是,假设您拥有管理员用户的角色(编辑/查看),您可以为“仅编辑”标签添加一个警卫。

    RouterModule.forChild([
      {
        path: 'admin',
        component: AdminComponent,
        canActivate: [AuthGuard],  //1 - redirect to login page if not logged in
        children: [
          //View Access
          {
            ......
          },
          //Edit Access
          {
            path: '',
            canActivateChild: [EditGuard], //2 - display "you don't have Edit permission to access this page"
            children: [
              { path: 'crises', component: ManageCrisesComponent },
              { path: 'heroes', component: ManageHeroesComponent },
              { path: '', component: AdminDashboardComponent }
            ]
          }
        ]
      }
    ])

答案 2 :(得分:3)

我也对angular2的angularGuard文档感到困惑。 CanActivate后卫和后卫之间的区别是什么? CanActivateChild警卫。

我有一些调查结果,希望这会对你有帮助。

auth-guard.service.ts文件

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url: string = state.url;

return this.checkLogin(url);
}

canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return this.canActivate(route, state);
}

因为在canActivate函数中调用了canActivateChild方法。您可以编写一段不会在canActivate函数中调用canActivateChild方法的代码片段。

答案 3 :(得分:2)

我能想到的一个原因是超时

我正在使用身份验证提供程序开始使用Angular 2。此提供程序将使一段空闲时间超过一定时间。

在您让计算机登录并且会话过期的常见情况下,您尝试的下一个导航必须验证您当前的情况。如果您在子路由之间导航,我认为CanActivateChild是将检测过期会话的警卫,并触发重定向登录,而CanActivate根本不会触发。

免责声明:这来自我的头脑,我还没有实现它。

答案 4 :(得分:0)

如果您定义了10个孩子,该怎么办。

然后canActivateChild仅在他们都有共同的要求时才需要排在一个地方,而不是每个孩子10 canActivate

答案 5 :(得分:0)

TL; DR: CanActivateCanActivateChild不适用于无组件路由。

我相信文档只是在无组件的路线中忽略了两个警卫的必要性,因为其目的仅仅是在文档的特定里程碑上演示无组件的路线,并在文档中使用两个防护。另一个。

在特定情况下,两个防护的使用可能非常有用,例如: 一个管理控制台,允许登录查看多个组件,例如邮件,日志统计信息,资源使用情况等。-在此级别,访问受到CanActivate防护的限制-尝试导航至每个组件时,每个管理员的角色- CanActivateChild保护人员检查用户。