Angular 5:条件模块延迟加载

dje*_*rid 7 angular-cli angular

我在尝试根据用户配置文件延迟加载模块时遇到问题,我定义了三个默认路径(每个路由的空路径)并且每个用户都可以访问特定模块,我正在使用守卫确定当前用户配置文件(实际上我是通过设置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
  }
];
Run Code Online (Sandbox Code Playgroud)

注意:如果有兴趣,请在在线问题下方 https://stackblitz.com/edit/angular-vd4oyu?file=app%2Fapp-routing.module.ts

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

Ted*_*rne 1

路由器只会在它匹配的第一条路由上尝试防护。由于此限制,您必须尝试两个选项之一。

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

第二个选项是拥有一条通用路由,''其路径上有另一个守卫,该守卫执行其他三个守卫的操作,然后路由到适当的模块。这听起来有点像黑客,但是,Angular 文档建议在 ToH 教程中这样做。

演示

警卫

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

路线

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
  }
];
Run Code Online (Sandbox Code Playgroud)