我正在尝试找到一种方法,根据用户的角色来有条件地渲染子路线的router-outlet
中的组件。
例如,我有一个DashboardComponent,它包含一个router-outlet
。我希望子router-outlet
中呈现的组件取决于令牌传递的用户角色而有所不同,而不必指定其他路由。
我希望尝试将我的路线写在靠近此的地方:
{
path: 'dashboard',
component: DashboardComponent,
children: [
{ path: '', component: DataViewsComponent }, // For standard user role
{ path: '', component: AdminViewsComponent } // For the admin user role
]
}
这种确切的模式当然行不通,因为路由器只能看到两条相同的路由路径。
我设法编写了一个使用canActivate
属性的服务来检查用户的角色,并转发到依赖于该角色的其他路由:
@Injectable()
export class RoleRouteRedirectService implements CanActivate {
roleRoutingPermissions: any = {
// Will contain redirects for every route in the app
// For this example, only contains reroutes for the dashboard route
['dashboard']: [
{ roles: [ 'user' ], redirect: '/dashboard/admin' },
{ roles: [ 'admin' ], redirect: '/dashboard/admin' }
]
};
constructor(private router: Router) {}
canActivate(route: ActivatedRouteSnapshot): boolean {
// In the larger app, the roles are taken out of the token
// Here I've mocked them from localStorage for ease
const userRoles: string[] = localStorage.getItem('user-role').split(',');
const url: string = route.data.url;
// Find the object property matching the desired origin URL
if (url in this.roleRoutingPermissions) {
// Iterate over the array of route permissions in this property
for (const item of roleRoutingPermissions[url]) {
// If we find the entry for the role, apply the redirect
if (item.roles.some(role => userRoles.includes(role))) {
this.router.navigate([ item.redirect ]);
return false;
}
}
}
// Otherwise, fail
console.log('Could not find matching route permissions');
return false;
}
}
这将使用不同的Routes模式:
{
path: 'dashboard',
component: DashboardComponent,
canActivate: [ RoleRouteRedirectService ],
data: {
url: 'dashboard'
},
// Conditional Routes
children: [
{
path: 'user',
component: DataViewsComponent,
},
{
path: 'admin',
component: AdminHomeComponent,
}
]
}
现在,这真的很好。但是,这种模式存在以下问题:
dashboard/user
,而只希望dashboard
可以为不同的用户呈现不同的孩子如果有人有任何想法,我很想听听他们的想法。我赞赏这是一个相对复杂的问题-如果我错过了任何有用的信息,请发表评论,然后我会看到可以添加的内容。
答案 0 :(得分:0)
一种替代方法是创建一个同时包含DataViewsComponent
和AdminHomeComponent
的父组件。根据用户的角色,可以通过ngIf
选择相关组件。然后,您可以将RoleRouteRedirectService
中的逻辑移到该父组件中:
<DataViewsComponent *ngIf="user.hasRole('user')"></DataViewsComponent>
<AdminHomeComponent *ngIf="user.hasRole('admin')"></DataViewsComponent>
答案 1 :(得分:0)
角度路由器将first-match-wins
策略用于定义的路由,与canActivate
结合使用是IMO在您的用例中可行的策略。我认为这种方法没有任何问题。
这是我实现路由的方法:
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'logout', component: HomeComponent },
{ path: '', component: AuthorizedComponent, canActivate: [AuthGuard], children: [
{ path: 'onboard', component: OnboardComponent, canActivate: [AuthGuard] },
{ path: 'onboard_requests', component: OnboardRequestsComponent, canActivate: [AuthGuard] },
{ path: 'employee_list', component: EmployeeListComponent, canActivate: [AuthGuard] },
{ path: 'employee_detail', component: EmployeeDetailComponent, canActivate: [AuthGuard] }
]
}]
虽然您的用例似乎与我的用例略有不同,但是您可以看到我使用了基于HomeComponent
的两个组件AuthorizedComponent
和canActivate
作为根路径