从服务动态确定loadChildren模块类型

时间:2018-02-13 13:33:20

标签: angular

在Angular应用程序中,我想确定要为指定路径加载的模块。这不是懒惰加载。这是关于动态路线配置/确定。

我有一个有3种访问权限的应用程序。每次访问都在他自己的模块中。在应用程序加载时,我想确定要加载的模块。在根路由级别和子级别。

在我看来,Angular在许多方面都非常灵活,但路由配置非常静态......

例如:

// routed module
const routes: Routes = [
  { path: '', loadChildren: () => getModuleType() }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
class ParentModule {}

// My problem is there, where can i put this function ???
getModuleType() {

  // How can I have the dependecy injected ???
  return someApiService.getProfile().map(profile => {

    if (profile === 'A') {
      return ProfileAModule;
    }

    if (profile === 'B') {
      return ProfileBModule;
    }

  });
}

// some feature module
@NgModule({})
class ProfileAModule {}

@NgModule({})
class ProfileBModule {}

1 个答案:

答案 0 :(得分:0)

我会使用受保护的功能模块来实现这一目标。

Feature X文件夹的文件夹结构示例和包含防护的Core文件夹(如果需要,可以有N个功能):

/core
    /guard
        / feature-x.guard.ts
/feature-x
    /feature-x.router.ts
    /feature-x.module.ts
    /feature-x.component.ts
    /feature-x-home
         /feature-x-home.module.ts
         /feature-x-home.router.ts
         /feature-x-home.component.ts
         /feature-x-home.component.html
         /feature-x-home.component.scss
    /feature-x-route1
         /feature-x-route1.module.ts
         /feature-x-route1.router.ts
         /feature-x-route1.component.ts
         /feature-x-route1.component.html
         /feature-x-route1.component.scss

特征X

每个功能都包含其限制路线。 feature-x.router.ts会是这样的:

const featureXRoutes: Route[] = [
  {
    path: '',
    component: RouteXFeatureComponent,
    canActivate: [ FeatureXGuard ],
    children: [
      { path: '', redirectTo: '/feature-x-home', pathMatch: 'full' },
      { path: 'feature-x-home', loadChildren: '@app/feature-x/feature-x-home/feature-x-home.module#FeatureXHomeModule' },
      { path: 'feature-x-route-1', loadChildren: '@app/feature-x/feature-x-route-1/feature-x-route-1.module#FeatureXRoute1Module' },
      // ... etc
    ]
  }
];

export const FeatureXRoutingModule: ModuleWithProviders = RouterModule.forChild(featureXRoutes);

@app是源路径文件夹的别名。如果您没有,请改用相对路径。延迟加载是可选的,但我强烈建议使用它。

feature-x-home.router.ts

const featureXHomeRoutes: Route[] = [{
    path: '',
    component: FeatureXHomeComponent
}];

export const featureXHomeRoutes: ModuleWithProviders = RouterModule.forChild(featureXHomeRoutes);

feature-x.module.ts

@NgModule({
  imports: [
    FeatureXRoutingModule
  ],
  declarations: [
    FeatureXComponent
  ]
})
export class FeatureXModule {}

feature-x.component.ts

@Component({
  selector: 'app-feature-x',
  template: '<router-outlet></router-outlet>',
  styleUrls: [ './feature-x.component.scss' ]
})
export class FeatureXComponent {}

您可以提供与当前功能相关的任何布局。

主模块

app.module.ts

@NgModule({
  imports: [
    CoreModule, // contains all guards declaration

    Feature1Module, // feature-x with x = 1
    Feature2Module, 
    Feature3Module,
    //... etc
    FeatureNModule,

    AppRoutingModule
  ],
  declarations: [
    AppComponent
  ],
  bootstrap: [ AppComponent ]

})
export class AppModule {}

如果您没有CoreModule,请在此处使用providers属性声明所有警卫。

app.router.ts

const appRoutes: Route[] = [
  { path: '', redirectTo: '/defaultRoute', pathMatch: 'full' },
  { path: '**', redirectTo: '/defaultRoute' }
];

export const AppRoutingModule: ModuleWithProviders = RouterModule.forRoot(appRoutes);

feature-x.module.ts

const FEATURE_X = 'YOUR_FEATURE_X';
@Injectable()
export class FeatureXGuard implements CanActivate {
  constructor(
    private profilService: ProfilService,
    private router: Router
  ) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    const canGo = this.profileService.hasProfil(FEATURE_X);

    if (!canGo) {
      this._router.navigate([ this.profileService.getDefaultRouteFor(FEATURE_X) ]);
    }

    return canGo;
  }
}

使用这个系统,根据他的个人资料,用户将被重定向到正确的&#34;家庭&#34;页。如果他试图访问他没有正确个人资料的页面,他将被重定向到他的家庭&#34;页

更新

您需要使用APP_BOOTSTRAP_LISTENER挂钩来注册应用路由,具体取决于您的用户个人资料。

https://stackblitz.com/edit/angular-vjfne6