Angular 5:条件模块延迟加载

时间:2018-03-21 11:34:30

标签: angular angular-cli

我在尝试根据用户配置文件延迟加载模块时遇到问题, 我定义了三个默认路径(每条路由都有空路径),每个用户都可以访问特定模块, 我正在使用警卫来确定当前的用户配置文件(实际上我是通过设置 const canGo = true 来手动切换以设置默认加载的模块)

预期的行为是实际的路由配置应该根据配置文件激活适当的路由,但事实并非如此。

export const routes: Routes = [
  {
    path: '',
    loadChildren: 'app/user/user.module#UserModule',
    canActivate: [
      CanActivateUserModuleGuard
    ],
  },
  {
    path: '',
    loadChildren: 'app/admin/admin.module#AdminModule',
    canActivate: [
      CanActivateAdminModuleGuard
    ]
  },
  {
    path: '',
    loadChildren: 'app/moderator/moderator.module#ModeratorModule',
    canActivate: [
      CanActivateModeratorModuleGuard
    ]
  },
  {
    path: '404',
    component: NotFoundComponent
  }
];

NB: 如果感兴趣,请在网上问题以下 node config

完成此要求的最佳方法是什么?

2 个答案:

答案 0 :(得分:0)

您忘记指定每条路线的路径:

export const routes: Routes = [
  {
    path: '',
    loadChildren: 'app/user/user.module#UserModule',
    canActivate: [
      CanActivateUserModuleGuard
    ],
  },
  {
    path: 'admin',
    loadChildren: 'app/admin/admin.module#AdminModule',
    canActivate: [
      CanActivateAdminModuleGuard
    ]
  },
  {
    path: 'moderator',
    loadChildren: 'app/moderator/moderator.module#ModeratorModule',
    canActivate: [
      CanActivateModeratorModuleGuard
    ]
  },
  {
    path: '404',
    component: NotFoundComponent
  }
];

可以找到完整的文档 here

答案 1 :(得分:0)

路由器只会尝试匹配的第一条路由上的守卫。由于这种限制,您必须尝试以下两个选项之一。

首先是实现一个自定义UrlMatcher,它将有效地完成你的守卫的工作,然后只在你想要加载的模块上匹配。如果您需要使用其他服务,这可能很困难,因为UrlMatcher只是一个函数,因此您不会获得任何DI。

第二个选项是使用路径为''的通用路由,该路由上有另一个保护,执行其他三个保护的操作,然后路由到相应的模块。这听起来有点像黑客,但Angular documentation建议在ToH教程中做到这一点。

Demo

保护

export class CanActivateModuleGuard implements CanActivate {

  constructor(private router: Router,
    private userGuard: CanActivateUserModuleGuard,
    private adminGuard: CanActivateAdminModuleGuard,
    private modGuard: CanActivateModeratorModuleGuard) { }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    let canGo = [{
      guard: this.adminGuard,
      url: 'admin',
    }, {
      guard: this.userGuard,
      url: 'user',
    }, {
      guard: this.modGuard,
      url: 'moderator',
    }].some((config) => {
      if (config.guard.canActivate(route, state)) {
        if (state.url !== `/${config.url}`) {
          this.router.navigate([config.url]);
        }
        return true;
      }
    });

    if (!canGo) {
      this.router.navigate(['/404']);
    }

    return canGo;
  }
}

路线

export const routes: Routes = [
  {
    path: '',
    canActivate: [CanActivateModuleGuard],
    children: [{
      path: 'user',
      loadChildren: 'app/user/user.module#UserModule',
      canActivate: [
        CanActivateUserModuleGuard
      ],
    },
    {
      path: 'admin',
      loadChildren: 'app/admin/admin.module#AdminModule',
      canActivate: [
        CanActivateAdminModuleGuard
      ]
    },
    {
      path: 'moderator',
      loadChildren: 'app/moderator/moderator.module#ModeratorModule',
      canActivate: [
        CanActivateModeratorModuleGuard
      ]
    }],
  },
  {
    path: '404',
    component: NotFoundComponent
  }
];