我想知道是否有任何方法可以根据角色有选择地加载模块。
e.g: - 有三组用户,即admin,biller和最终用户。根据他们的角色,他们将被授权使用某些功能。该应用程序基于相同的用户组分为三个模块,其中一个共享模块由所有这些模块共享。 基于登录,是否可以选择性地仅加载该特定用户所需的模块?
注意: - 所有路由路径都相同,例如/ home,/ dashboard,/ sales等
添加一个点: 在上面的场景中,假设我生成了四个文件 - admin.chunk.js,biller.chunk.js,end-user.chunk.js和common模块将热切地加载app js。 根据用户登录,从后端,我有选择地发送适合该登录用户的js。现在所有组件的路径都是相同的,除了管理员可以访问多个模块而不是最终用户的部分。在这种情况下如何管理路由......?
答案 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)
基本上,实施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