基于选择角色的模块加载

时间:2017-12-06 08:01:29

标签: angular

我想知道是否有任何方法可以根据角色有选择地加载模块。

e.g: - 有三组用户,即admin,biller和最终用户。根据他们的角色,他们将被授权使用某些功能。该应用程序基于相同的用户组分为三个模块,其中一个共享模块由所有这些模块共享。 基于登录,是否可以选择性地仅加载该特定用户所需的模块?

注意: - 所有路由路径都相同,例如/ home,/ dashboard,/ sales等

添加一个点: 在上面的场景中,假设我生成了四个文件 - admin.chunk.js,biller.chunk.js,end-user.chunk.js和common模块将热切地加载app js。 根据用户登录,从后端,我有选择地发送适合该登录用户的js。现在所有组件的路径都是相同的,除了管理员可以访问多个模块而不是最终用户的部分。在这种情况下如何管理路由......?

5 个答案:

答案 0 :(得分:0)

是的,你可以做到这一点我在我的项目中做了类似的事情。它基于这种环境。你必须看过环境文件,每个.ts文件代表一个基于我设置我的提供者的环境加载的环境,

providers: environment.production?[MyService1]:[MyService1, MyService2],

在上面的示例中,我将基于我的环境在module.ts中加载我的服务,如果它不是生产,这个三元运算符将在提供者中加载我的两个服务,否则它只会注入一个。

environment.production是一个布尔变量。

同样可以应用于@ngmodule的导入和其他属性,这样我们可以配置具有多个行为的单个模块。

检查一下,

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS, HttpClientModule, HttpClient, HttpParams } from '@angular/common/http';
import {DatePipe} from '@angular/common';

import { AppComponent } from './app.component';
import { MYInterceptor} from '../mocks/my-interceptor';

import { MyNameServiceService } from '../services/my-name-service.service';
import { MyNameComponent } from './display-name/my-name.component';
import { environment } from '../environments/environment';

@NgModule({
  declarations: [
    AppComponent,
    DisplayNameComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: environment.production?[MyNameServiceService, DatePipe]:[DatePipe,MyNameServiceService, {provide: HTTP_INTERCEPTORS,useClass: MYInterceptor,multi: true}],
  bootstrap: [AppComponent]
})
export class AppModule { }

答案 1 :(得分:0)

Guards

基本上,实施CanActivate防护并使用它。

import { Injectable }     from '@angular/core';
import { CanActivate }    from '@angular/router';
import { AuthService }    from './somewhere';

@Injectable()
export class AdminGuard implements CanActivate {
  constructor(private authService: AuthService) {}
  canActivate() {
    if (this.authService.isAuthenticated() && this.authService.isAdmin()) {
      console.log('You are admin, go through!');
      return true;  
    }
    return false;
  }
}

然后在路由器中:

const routes: Routes = [
  { path: 'peasants', component: PeasantComponent },
  { path: 'kings', component: PeasantComponent, canActivate: [AdminGuard] },
]

编辑:你想基于此加载模块。嗯,同样的:

const routes: Routes = [
  { path: 'peasants', component: PeasantComponent },
  { path: 'kings', loadChildren: 'some/path/to/admin.module', canActivate: [AdminGuard] },
]

答案 2 :(得分:0)

是的,CanLoad auth guard可用于加载授权用户或角色的模块。实现CanLoad接口以检查用户的权限,如果用户授权,则返回true,否则重定向到错误页面。

请注意:预加载策略无法加载受CanLoad保护的功能模块。 The CanLoad takes precedence over the pre-load strategy.预加载/急切加载模块必须依赖于CanActivate防护。

答案 3 :(得分:0)

是的,您可以使用Angular的CanLoad界面来实现。我在下面提到了一个代码示例。您可以使用任何模块延迟加载策略。当您拥有大型应用程序并且不想加载所有模块(如果用户不使用它)并且减小Web应用程序的下载大小时,它会很有用。

load-admin-module.guard.ts

import {Injectable} from "@angular/core";
import {CanLoad, Route} from "@angular/router";
import {AuthService} from "@core/services/auth.service";

@Injectable({
  providedIn: "root"
})
export class LoadAdminModuleGuard implements CanLoad {
  constructor(private authService: AuthService) {
  }
  canLoad(route: Route): boolean {
    let url: string = route.path;
    console.log("Admin Module Load Guard - Url:" + url);
    return this.authService.isAdmin;
  }
}

auth.service.ts

import {throwError as observableThrowError, Observable} from "rxjs";
import {HttpService} from "@app/shared/services/http.service";
import {SharedActions} from "@app/shared/actions/shared.actions";

import {Injectable} from "@angular/core";
import {Http, Response} from "@angular/http";
import {AppState} from "@app/interfaces";
import {Store} from "@ngrx/store";
import {AuthActions} from "@app/auth/actions/auth.actions";
import {map, catchError} from "rxjs/operators";
import {getAuthStatus} from "@app/auth/reducers/selectors";

// import 'rxjs/Rx';


@Injectable()
export class AuthService {

  public userLoggedIn: boolean;
  public currentUser: any;
  public isAdmin: boolean;
  private oauthUrl = "/api/user/login";
  private usersUrl = "/api/user/profile";
  private _returnUrl = "/";

  constructor(private http: Http,
              private httpService: HttpService,
              private actions: AuthActions,
              private sharedActions: SharedActions,
              private store: Store<AppState>) {
    this.getCurrentUser();
  }

  .........
  .........

}

现在,可以在您的 app.router.ts 文件中使用它,如下所示:

export const appRoutes: Routes = [
     {
       path: "", component: HomeNewComponent, pathMatch: "full",
       data: {animation: "home"}
     },
     {
        path: "",
        loadChildren: "./admin/admin.module#AdminModule",
        canActivate: [AuthGuard, AdminGuard],
        canLoad: [LoadAdminModuleGuard]
      },
    ];


@NgModule({
  imports: [
    RouterModule.forRoot(appRoutes, {
      useHash: false,
      preloadingStrategy: env.production ? PreloadAllModules : null
      // preloadingStrategy: PreloadAllModules
    })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {
}

答案 4 :(得分:0)

我将gnx-persmission用于基于角色的模块,组件,元素可访问性。 参考:https://www.npmjs.com/package/ngx-permissions