我正在尝试创建一个基于角色的路由系统,其中app-routing
模块有多个模块路由到同一路由。
例如。
const routes: CustomRoutes = [
{ path: 'login', component: LoginFormComponent },
{
path: '',
canActivate: [CanActivateRole],
data: {
roles: UserType.ClientRoleType
},
pathMatch: 'full',
loadChildren: () => { return ClientModule; },
},
{
path: '',
canActivate: [CanActivateRole],
data: {
roles: UserType.DCRoleType
},
pathMatch: 'full',
loadChildren: () => { return DcEmpModule; },
},
];
canActivateRole
正在读取以route.data.roles
确定它是否可以路由到loadChildren
.
注意:我已尝试使用matcher
配置路由以加载单独的模块,如
本答案
或
本中所示,但是由于我正在使用服务,所以我找不到这样做的方法。如果有一种方法可以使用匹配器中的服务。
更新 1:有些人要求我使用服务来确定要加载的模块,所以我创建了一个近似的canActivate
外观。
@Injectable()
export class CanActivateRole implements CanActivate {
constructor(private auth: AuthService, private router: Router) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
// If not logged in
if (this.auth.notLoggedIn() || this.auth.UserType == null) {
this.router.navigateByUrl('/login');
return false;
}
let routeData = route.data as CustomRouteData;
if (routeData.roles == undefined) {
// Is authenticated but no roles specified so allowed through
return true;
}
else if (Array.isArray(routeData.roles)) {
routeData.roles.forEach(allowedRole => {
if (this.auth.allowParentPermission(allowedRole, this.auth.UserType)) {
return true;
}
return false;
});
}
else {
if (this.auth.allowParentPermission(routeData.roles, this.auth.UserType)) {
return true;
}
}
return false;
}
}
我尝试做的另一种选择是某种服务,它返回要加载的模块loadChildren
@Injectable()
export class RouteMatcher {
constructor(private auth: AuthService) {}
/**
* Used to match user roles to route to modules.
*
* To use return function in loadChildren key in routes eg.
* ```
* {
* path: '',
* loadChildren: () => return userRoleModuleMatcher(obj);
* }
* ```
*
* `Obj`: A map of which UserType or list of UserTypes will be matched onto a module. That module will route all of it's children to the original router. Eg.
* `[[DCRoleType, EmpRoleType], EmpModule]`
* will match both `DCRoleType` and `EmpRoleType` onto the `EmpModule`
*/
public userRoleModuleMatcher(
obj: ReadonlyMap<
typeof UserType.UserType[] | typeof UserType.UserType,
any
>
): any {
obj.forEach((module, allowedRoles) => {
if (Array.isArray(allowedRoles)) {
allowedRoles.forEach(role => {
if (this.auth.allowParentPermission(role, this.auth.UserType)) {
return module;
}
});
}
else {
if (this.auth.allowParentPermission(allowedRoles, this.auth.UserType)) {
return module;
}
}
// If there are no matching permissions then route to shared module which has Server Error component
return SharedModule;
});
}
}