在 angular 5 中 show/hide 一个 link 的最佳方法
Best way to show/hide a link in angular 5
我目前有一个主页,可以路由到我公司运行的所有不同工作流程。我们有大约 15 个不同的工作流程,每个工作流程都由一个用户角色保护。如果您在数据库中没有正确的用户角色,您将看不到该页面对应的 link。我们保护服务器端点,但我担心的是向人们展示 link 或不向他们展示的最佳方式是什么我宁愿不重复代码。
这是一种方法:
我有一个 html 这样的页面
<ul>
<li *ngIf="authService.hasRequiredRole('users.user-admin')" routerLink="/user">Users</li>
<li *ngIf="authService.hasRequiredRole('users.role-admin')" routerLink="/role">Roles</li>
</ul>
我有这样的授权服务:
hasRequiredRole(roles: string | [string]) {
if (typeof roles === 'string') {
roles = [roles];
}
for (const roleSlug of roles) {
if (this.user.roles.find((role: any) => {
return role.slug === roleSlug;
})) {
return true;
}
}
return false;
}
我有一个路由器,路由如下:
const routes: Routes = [{
path: 'user',
data: {
allowedRoles: 'users.user-admin'
},
loadChildren: 'app/user/user.module#UserModule',
canActivate: [AuthGuard]
},
{ path: 'home', component: HomeComponent }]
AuthGuard 只检查用户是否登录,然后使用路由中的数据检查用户是否具有正确的角色。
如您所见,我们在两个不同的位置使用了字符串 'users.user-admin'。
我想我们应该有一个带两个守卫的路由器。一名警卫将检查用户是否已登录,另一名警卫将检查用户是否具有正确的角色。该角色将像这样硬编码:
export class UserAdminGuard implements CanActivate {
constructor(private router: Router, private authService: AuthService) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable < boolean > | Promise < boolean > | boolean {
return this.authService.hasRequiredRole('users.user-admin');
}
}
然后 html 看起来像这样:
<ul>
<li *ngIf="userAdminGuard.canActivate()" routerLink="/user">Users</li>
<li *ngIf="roleAdminGuard.canActivate()" routerLink="/role">Roles</li>
</ul>
我的方法是否可行,或者是否有更好的 angular 方法?我在文档中找不到任何关于此类的内容。如果还可以提供文档加分。
我认为一种方法是创建结构指令。您可以创建一个 RolesDirective,它根据您传递的角色处理 showing/hiding 内容的逻辑。
例如:
你的指令看起来像这样
@Directive({
selector: '[roles]',
inputs: ['roles']
})
export class RolesDirective {
constructor(private _templateRef: TemplateRef<any>,
private _viewContainer: ViewContainerRef,
private userService: UserService) {
}
@Input() set roles(allowedRoles: Array<string>) {
let shouldShow: boolean = false;
let userRoles:Array<string> = this.userService.getUserRoles();
for(let role of userRoles){
if(role.toUpperCase() == "ADMIN"){
shouldShow = true;
break;
}
for(let allowedRole of allowedRoles){
allowedRole = allowedRole.toUpperCase();
if(allowedRole.toUpperCase() == role.toUpperCase()){
shouldShow = true;
break;
}
}
}
if (shouldShow) {
this._viewContainer.createEmbeddedView(this._templateRef);
} else {
this._viewContainer.clear();
}
}
}
然后在您的 html 中传递该组件允许的角色
<ul>
<li *roles="['admin']" routerLink="/user">Users</li>
<li *roles="['other','roles']" routerLink="/role">Roles</li>
</ul>
我目前有一个主页,可以路由到我公司运行的所有不同工作流程。我们有大约 15 个不同的工作流程,每个工作流程都由一个用户角色保护。如果您在数据库中没有正确的用户角色,您将看不到该页面对应的 link。我们保护服务器端点,但我担心的是向人们展示 link 或不向他们展示的最佳方式是什么我宁愿不重复代码。
这是一种方法:
我有一个 html 这样的页面
<ul>
<li *ngIf="authService.hasRequiredRole('users.user-admin')" routerLink="/user">Users</li>
<li *ngIf="authService.hasRequiredRole('users.role-admin')" routerLink="/role">Roles</li>
</ul>
我有这样的授权服务:
hasRequiredRole(roles: string | [string]) {
if (typeof roles === 'string') {
roles = [roles];
}
for (const roleSlug of roles) {
if (this.user.roles.find((role: any) => {
return role.slug === roleSlug;
})) {
return true;
}
}
return false;
}
我有一个路由器,路由如下:
const routes: Routes = [{
path: 'user',
data: {
allowedRoles: 'users.user-admin'
},
loadChildren: 'app/user/user.module#UserModule',
canActivate: [AuthGuard]
},
{ path: 'home', component: HomeComponent }]
AuthGuard 只检查用户是否登录,然后使用路由中的数据检查用户是否具有正确的角色。
如您所见,我们在两个不同的位置使用了字符串 'users.user-admin'。
我想我们应该有一个带两个守卫的路由器。一名警卫将检查用户是否已登录,另一名警卫将检查用户是否具有正确的角色。该角色将像这样硬编码:
export class UserAdminGuard implements CanActivate {
constructor(private router: Router, private authService: AuthService) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable < boolean > | Promise < boolean > | boolean {
return this.authService.hasRequiredRole('users.user-admin');
}
}
然后 html 看起来像这样:
<ul>
<li *ngIf="userAdminGuard.canActivate()" routerLink="/user">Users</li>
<li *ngIf="roleAdminGuard.canActivate()" routerLink="/role">Roles</li>
</ul>
我的方法是否可行,或者是否有更好的 angular 方法?我在文档中找不到任何关于此类的内容。如果还可以提供文档加分。
我认为一种方法是创建结构指令。您可以创建一个 RolesDirective,它根据您传递的角色处理 showing/hiding 内容的逻辑。
例如:
你的指令看起来像这样
@Directive({
selector: '[roles]',
inputs: ['roles']
})
export class RolesDirective {
constructor(private _templateRef: TemplateRef<any>,
private _viewContainer: ViewContainerRef,
private userService: UserService) {
}
@Input() set roles(allowedRoles: Array<string>) {
let shouldShow: boolean = false;
let userRoles:Array<string> = this.userService.getUserRoles();
for(let role of userRoles){
if(role.toUpperCase() == "ADMIN"){
shouldShow = true;
break;
}
for(let allowedRole of allowedRoles){
allowedRole = allowedRole.toUpperCase();
if(allowedRole.toUpperCase() == role.toUpperCase()){
shouldShow = true;
break;
}
}
}
if (shouldShow) {
this._viewContainer.createEmbeddedView(this._templateRef);
} else {
this._viewContainer.clear();
}
}
}
然后在您的 html 中传递该组件允许的角色
<ul>
<li *roles="['admin']" routerLink="/user">Users</li>
<li *roles="['other','roles']" routerLink="/role">Roles</li>
</ul>