在 Angular 中的同一路径上有条件地加载不同模块

Conditionally Load Different Modules on the Same Path in Angular

我有一个多用户 Angular 应用程序,每个用户都有一个模块(因为他们有完全不同的可访问页面),如下所示:

从登录页面(/login 来自 app-routing),我想根据用户提供的凭据重定向到每个模块,但是 NOT使用 children 路线,例如 /user /admin/guest

相反,当管理员登录时,我希望重置 URL。因此,例如,管理员不应看到路径 /admin/user-management/admin/configuration;它只是访问 /user-management/configuration

这可能吗?如果我有 adminuser/configuration 路由,会有问题吗?

编辑: 这是一个 Stackblitz working example。登录后查看 URL 路由。

编辑 2: 在 Stackblitz 示例中,您可以在 master 上看到原始问题,在 solution 分支上看到工作解决方案。

我猜你的延迟加载配置看起来像这样:

  {
    path: 'config',
    loadChildren: () => import('./pages/userConfig/userConfig.module').then( m => m.UserConfigPageModule),
  },

您可以将箭头函数转换为普通函数,例如一个 switch 语句来决定你想要加载的模块:

  {
    path: 'config',
    loadChildren: () => {
      switch(userType) {
        case 'IsAdmin':
          return import('./pages/adminConfig/adminConfig.module').then( m => m.AdminConfigPageModule);
        case 'IsUser':
          return import('./pages/userConfig/userConfig.module').then( m => m.UserConfigPageModule);
        default:
          return import('./pages/guestConfig/guestConfig.module').then( m => m.GuestConfigPageModule);
      }
    },
    canActivate: [ConfigGuard],
  },

工作stackblitz

Note:
After logout you need to refresh the stackblitz view otherwise it kinda glitches. I'll look into it later.

解决方案:

经过大量调查,我发现可以通过创建路由来完成 matcher

代码:

我设法让它与你的代码一起工作。这是工作示例: https://stackblitz.com/edit/angular2-routing-test-qj4geu?file=src/app/user/user.component.html

这是app-routing.module.ts上的相关代码:

const routes: Routes = [
  {
    path: 'login',
    component: LoginComponent
  },
  {
    matcher: url => {
      const user_type = localStorage.getItem('user_type');
      if (user_type === 'user') {
        return url.length ? { consumed: [] } : { consumed: url };
      }
      return null;
    },
    loadChildren: () => import('./user/user.module').then(m => m.UserModule)
  },
  {
    matcher: url => {
      const user_type = localStorage.getItem('user_type');
      if (user_type === 'admin') {
        return url.length ? { consumed: [] } : { consumed: url };
      }
      return null;
    },
    loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
  },
  {
    matcher: url => {
      const user_type = localStorage.getItem('user_type');
      if (user_type === 'guest') {
        return url.length ? { consumed: [] } : { consumed: url };
      }
      return null;
    },
    loadChildren: () => import('./guest/guest.module').then(m => m.GuestModule)
  },
  {
    path: '',
    pathMatch: 'full',
    redirectTo: 'login'
  }
];

注意:

如此处所述:https://github.com/angular/angular/issues/23866#issuecomment-388527483,当我们使用路由 matcher 时,我们需要指定 url 的哪一部分被 matcher 函数使用,以及剩余部分将发送到嵌套路由器。

博客:

这里有两篇博文,其中有深入的细节和操作步骤:

博客 1:https://medium.com/@brandontroberts/custom-route-matching-with-the-angular-router-fbdd48665483

博客 2:https://medium.com/@lenseg1/loading-different-angular-modules-or-components-on-routes-with-same-path-2bb9ba4b6566