创建自定义的 Angular 指令 (3)
2022-05-16 本文已影响0人
品品下午茶
在一个典型的 Angular 企业应用中,用户会被分配若干角色,角色又被分配相应的功能权限。于是,用户就可以访问其角色对应的应用功能,也称基于角色的访问控制(Role-based Access Control)。
本文会介绍如何创建一个自定义的结构指令,该指令会验证用户的角色,显示或移除应用功能的视图模板。
创建指令文件
首先,通过 Angular CLI 命令,创建指令的源代码文件。
ng generate directive permission
命令输出结果:
CREATE src/app/permission.directive.spec.ts (240 bytes)
CREATE src/app/permission.directive.ts (149 bytes)
UPDATE src/app/app.module.ts (696 bytes)
角色属性
打开 src/app/permission.directive.ts
指令文件,添加下列属性:
@Input() appPermission: string[];
private currentRole = ‘admin’;
-
appPermission
属性是一个输入属性,可以接收父级组件传入的角色数据的数组,表示用户必须具有数组中的角色之一,才可以访问该组件。 -
currentRole
属性则表示当前用户所具有的角色。
角色验证
在 permission
组件类的构造函数中,添加两个参数:
constructor(private tmplRef: TemplateRef<any>, private vc: ViewContainerRef) {}
-
TemplateRef
:Angular 生成的视图模板。 -
ViewContainerRef
:装载视图模板的容器。
在 ngOnInit
方法中,添加权限验证的逻辑:
ngOnInit() {
if (this.appPermission.indexOf(this.currentRole) === -1) {
this.vc.clear();
} else {
this.vc.createEmbeddedView(this.tmplRef);
}
}
如果 currentRole
表示的角色,出现在角色列表中,ViewContainerRef
会把产生的视图模板添加到 DOM 中,否则,从 DOM 中移除该视图模板。
页面效果
normal角色展示效果检查视图模板代码:
<div _ngcontent-kqs-c15=“”>
<p _ngcontent-kqs-c15="">['admin', 'normal']</p>
</div>
<!—bindings={
"ng-reflect-app-permission": "admin,normal”
}—>
<!—bindings={
"ng-reflect-app-permission": “admin”
}—>
admin角色展示效果
检查视图模板代码:
<div _ngcontent-rry-c15=“”>
<p _ngcontent-rry-c15="">['admin', 'normal']</p>
</div>
<!—bindings={
"ng-reflect-app-permission": "admin,normal”
}—>
<div _ngcontent-rry-c15=“”>
<p _ngcontent-rry-c15="">['admin']</p>
</div>
<!—bindings={
"ng-reflect-app-permission": “admin”
}—>
源代码
src/app/permission.directive.ts
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core’;
@Directive({
selector: '[appPermission]’
})
export class PermissionDirective {
// The name of the input property must have
// the same name as the selector of the directive
@Input() appPermission: string[];
private currentRole = ‘admin’;
constructor(private tmplRef: TemplateRef<any>, private vc: ViewContainerRef) {
}
ngOnInit() {
if (this.appPermission.indexOf(this.currentRole) === -1) {
this.vc.clear();
} else {
this.vc.createEmbeddedView(this.tmplRef);
}
}
}
src/app/app.component.html
<p>
<input type="text” appAlphabet>
</p>
<div *appPermission="['admin', 'normal’]”>
<p>['admin', 'normal']</p>
</div>
<div *appPermission="['admin’]”>
<p>['admin']</p>
</div>