粒度控制

写在前面

很多时候需要对某个按钮进行权限控制,@delon/acl 提供一个 acl 指令,可以利用角色或权限点对某个按钮、表格、列表等元素进行权限控制。

原理

[acl] 默认会在目标元素上增加一个 acl__hide 样式,利用 display: none 来隐藏未授权元素,它是一个简单、又高效的方式。

以此相对应的 *aclIf 是一个结构型指令,它类似 ngIf 在未授权时会不渲染该元素。注: 为了保持简洁它并不支持 acl-ability 权限点配置。

示例

角色

按钮必须拥有 user 角色显示。

  1. <button [acl]="'user'"></button>
  2. <button *aclIf="'user'"></button>

按钮必须拥有 user 或 manage 角色显示。

  1. <button [acl]="['user', 'manage']"></button>
  2. <button *aclIf="['user', 'manage']"></button>

按钮必须拥有 user 和 manage 角色显示。

  1. <button [acl]="{ role: ['user', 'manage'], mode: 'allOf' }"></button>
  2. <button *aclIf="{ role: ['user', 'manage'], mode: 'allOf' }"></button>

当拥有 user 角色显示文本框,未授权显示文本。

  1. <input nz-input *aclIf="'user'; else unauthorized">
  2. <ng-template #unauthorized>{{user}}</ng-template>

使用 except 反向控制,当未拥有 user 角色时显示。

  1. <ng-template [aclIf]="role" except>
  2. <input nz-input>
  3. </ng-template>

权限点

按钮必须拥有 10 权限点显示。

  1. <button [acl]="10"></button>

acl 指令为了能所传递的值是角色还是权限点,所以以 string 类型表示角色、number 类型表示权限点,若权限点为字符串,可使用以下写法。

  1. <button acl [acl-ability]="'USER-EDIT'"></button>

使用 mode: 'allOf' 表示必须同时拥有。

  • oneOf 表示只须满足角色或权限点数组中的一项算有效(默认)

  • allOf 表示必须满足所有角色或权限点数组算有效

按钮必须拥有 10USER-EDIT 权限点时显示。

  1. <button [acl]="{ ability: [10, 'USER-EDIT'], mode: 'allOf' }"></button>

字符串型权限点

检查权限是通过 can 方法,通过全局配置 acl.preCan 方法,可以利用该方法来实现一个字符串区分角色或权限点。

  1. // global-config.module.ts
  2. const alainConfig: AlainConfig = {
  3. acl: {
  4. preCan: (roleOrAbility) => {
  5. const str = roleOrAbility.toString();
  6. return str.startsWith('ability.') ? { ability: [ str ] } : null;
  7. }
  8. }
  9. };

因此,当传递一个带有 ability. 开头的字符串会被认为这是一个权限点,例如:

  1. <button acl="ability.user.edit"></button>

API

*aclIf

参数说明类型默认值
[aclIf]can 方法参数体ACLCanType-
[aclIfThen]已授权时显示模板TemplateRef<void> | null-
[aclIfElse]未授权时显示模板TemplateRef<void> | null-
[except]未授权时显示booleanfalse