Angular 5:有条件地设置默认路由

Angular 5: Conditionally Set Default Route

我有一个导航,其中包含三个子菜单及其相应的子路径。现在有些子菜单不可见 (ngIf),具体取决于用户从服务器获得的声明。

点击主菜单后,我重定向到其中一个子菜单,但有时无法访问此子菜单 - 然后我想重定向到下一个同级:

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

现在 "sometimes" 我可以计算了。我尝试创建三个具有空路径 ('') 和 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] },
    ]
}

希望我可以使用路由和我的规则到 return false 以防万一 submenu1 不可见并且路由器会选择下一个可能的路线(重定向到 submenu2)。

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

最好的方法是什么?

您的路由守卫从未被调用的原因是包含 redirect 的路由定义在所有情况下都被假定为只是重定向。所以 Angular 接受重定向,因为只要用户点击我想立即重定向的这条路径。路由守卫在这种情况下不会生效。

要实现您正在寻找的内容,您可能需要将重定向移动到您的路由守卫中。除了 return 判断 true 和 false 之外,路由守卫还可以在转换期间重定向而不是取消它。

首先,您需要删除路由对象中的重定向

接下来,路由守卫的逻辑

  1. 检查用户是否可以访问此路由
  2. 如果是,让用户继续路由
  3. 如果没有将用户重定向到新路由并且之后 return false

只需将 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