角度5:有条件地设置默认路线

时间:2018-06-05 12:59:40

标签: angular angular-router angular-router-guards

我有一个带有三个子菜单的导航和他们的相应儿童路线。现在一些子菜单不可见(ngIf),具体取决于用户从服务器获得的声明。

单击主菜单后,我会重定向到其中一个子菜单,但有时这个子菜单无法访问 - 那么我想重定向到下一个兄弟:

{
    path: 'mymainmenue',
    children: [
        { path: 'submenu1', component: SubMenu1Component },
        { path: 'submenu2', component: SubMenu2Component },
        { path: 'submenu3', component: SubMenu3Component },
        { path: '', redirectTo: 'submenu1' },
    ]
}

现在"有时"我能够计算出来。我尝试使用空路径('')和CanActivate - Guard创建三条路线。与此类似:

{
    path: 'mymainmenue',
    children: [
        { path: 'submenu1', component: SubMenu1Component },
        { path: 'submenu2', component: SubMenu2Component },
        { path: 'submenu3', component: SubMenu3Component },
        { path: '', redirectTo: 'submenu1', canActivate: [ClaimsGuard] },
        { path: '', redirectTo: 'submenu2', canActivate: [ClaimsGuard] },
        { path: '', redirectTo: 'submenu3', canActivate: [ClaimsGuard] },
    ]
}

希望我可以使用路线和我的规则返回false以防例如子菜单不可见,路由器会选择下一条可能的路线(重定向到子菜单2 )。

我的方法存在的问题是redirectTo甚至在调用canActivate - 方法之前就已执行。

最好的方法是什么?

1 个答案:

答案 0 :(得分:0)

永远不会调用路由保护的原因是,在所有情况下,假定包含redirect的路由定义只是重定向。因此,当用户点击此路径时,Angular会重定向,我希望立即重定向。在这种情况下,路线防守并没有生效。

要实现您所寻找的目标,您可能需要将重定向移动到您的路线保护中。除了返回true和false之外,路线保护员还可以在转换期间重定向而不是取消它。

首先,您希望删除路线对象中的重定向

接下来,路线保护的逻辑

  1. 检查用户是否可以访问此路由
  2. 如果是,请让用户继续路由
  3. 如果没有将用户重定向到新路由并且之后返回false
  4. 只需将Router注入您的路线保护并调用this.router.navigate(['theNextSubmenuState']);即可实现重定向。

    这种路线防守的一个例子可能如下所示:

    @Injectable()
    export class ClaimsGuard implements CanActivate {
      constructor(private router: Router, private yourClaimsService: YourClaimsService) {}
    
      canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        return this.checkClaimsAccess(state);
      }
    
      private checkClaimsAccess(state: RouterStateSnapshot) {
        if(this.yourClaimsService.userHasAccess(state) {
          return true;
        } else {
          const nextSubmenu = this.getNextSubmenuState(state);
          this.router.navigate([nextSubmenu])
          return false;
        }
      }
    
      private getNextSubmenuState(state: RouterStateSnapshot): string {
        //Some logic to figure out which submenu state you would like to go to next
      }
    }
    

    Angular还为路线保护中的重定向如何处理其路由文档提供了一个很好的示例 - 请查看本节的第二代码示例 - > https://angular.io/guide/router#teach-authguard-to-authenticate