我想基于用户角色在同一(“”)路径(主页)上加载特定的Angular模块。假设我有两个名为AdminModule和OperatorModule的模块。如果角色是ADMIN,则我要加载AdminModule,否则要加载OperatorModule。我想使用Angular Guard将其存档。
现在在app.routing.ts
中,我添加了以下代码:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AuthGuard } from './core/guards/auth.guard';
import { AdminModule } from './modules/admin';
import { OperatorModule } from './modules/operator';
const routes: Routes = [
{
path: '',
loadChildren: () => AdminModule,
canLoad: [ AuthGuard ],
data: { role: 'ADMIN' }
},
{
path: '',
loadChildren: () => OperatorModule,
canLoad: [ AuthGuard ],
data: { role: 'OPERATOR' }
},
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
我用以下代码实现了AngularGuard,该代码必须显示OperatorModule:
import { Injectable } from '@angular/core';
import { CanLoad, Route, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanLoad {
constructor(private router: Router) {}
canLoad(route: Route): Promise<boolean> | boolean {
if (route.data.role === 'OPERATOR') {
return true;
}
return false;
}
}
第一条路线失败后,它会以某种方式停止寻找,我做错了什么吗?
djerid的StackBlitz示例:https://stackblitz.com/edit/angular-vd4oyu?file=app%2Fapp-routing.module.ts
===
Matcher也不起作用:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AuthGuard } from './core/guards/auth.guard';
import { AdminModule } from './modules/admin';
import { OperatorModule } from './modules/operator';
const routes: Routes = [
{
loadChildren: () => AdminModule,
matcher: AdminMatcher,
data: { role: 'NO' }
},
{
loadChildren: () => OperatorModule,
matcher: OperatorMatcher,
data: { role: 'OPERATOR' }
},
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {
constructor() {
}
}
import { UrlSegment, UrlSegmentGroup, Route } from '@angular/router';
export function AdminMatcher(segments: UrlSegment[], group: UrlSegmentGroup, route: Route) {
const isPathMatch = segments[0].path === route.path;
if (isPathMatch && route.data.role === 'ADMIN') {
return { consumed: [segments[0]] };
} else {
return null;
}
}
export function OperatorMatcher(segments: UrlSegment[], group: UrlSegmentGroup, route: Route) {
const isPathMatch = segments[0].path === route.path;
if (isPathMatch && route.data.role === 'OPERATOR') {
return { consumed: [segments[0]] };
} else {
return null;
}
}
答案 0 :(得分:0)
最好是使用UrlMatchers而不是canLoad,以根据您的条件匹配每一个,当两个路径之一匹配时,另一个将自动被忽略
const routes: Routes = [{
path: '',
matcher: adminMatcher,
oadChildren: () => AdminModule,
data: { role: 'ADMIN' }
},
{
path: '',
matcher: operatormatcher,
loadChildren: () => OperatorModule,
data: { role: 'OPERATOR' }
}]
选中此example
答案 1 :(得分:0)
这是一个古老的问题,但是如果有人偶然发现了这个问题,我在这里留下一个答案。我通过在延迟加载的路由中使用根模块的injector
解决了这个问题。
您可以在stackblitz上查看有效的解决方案。
创建一个导出ReplaySubject<Injector>
的新文件。
import { Injector } from '@angular/core';
import { ReplaySubject } from 'rxjs';
// Feel free to optimize this implementation if you want to
// expose `Observable<Injector>` instead of the subject itself.
export const appInjector = new ReplaySubject<Injector>();
在main.ts
中,获取根模块Injector
的句柄,并将其发布到您在上面创建的appInjector
主题中:
platformBrowserDynamic()
.bootstrapModule(AppModule)
.then((m) => appInjector.next(m.injector)) // publish root module's injector
.catch((err) => console.error(err));
这是我们修改路由的步骤,该路由需要基于某些异步条件异步延迟加载不同的模块。
const routes: Routes = [
// other routes
// ...
// ...
// conditional route
{
path: "dashboard",
component: LayoutComponent,
canActivate: [DashboardAuthGuard], // block this route if user is not logged-in
loadChildren: () =>
// Use the appInjector subject
appInjector.pipe(
// ...to get a handle to your AuthService
map((injector) => injector.get(AuthService)),
// ...then switch to a new observable
switchMap((authService) => {
// ...that uses authService to retrieve the logged-in user
return authService.user$.pipe(
// ...then switches again, this time to actually lazy-load a feature module
switchMap((user) => {
// ...but first let's check the user's role
switch (user.role) {
// ...and load Admin Feature Module if user.role is 'admin'
case "admin":
return import(
"./modules/admin-dashboard/admin-dashboard.module"
).then((m) => m.AdminDashboardModule);
// ...or load User Feature Module if user.role is 'user'
case "user":
return import(
"./modules/user-dashboard/user-dashboard.module"
).then((m) => m.UserDashboardModule);
}
})
);
})
),
},
];