Angular Material:如何通过自定义指令禁用matInput输入框
问题原因
Angular Material 的 matInput 指令内部通过自身的 @Input() disabled 属性统一控制输入框的禁用状态、关联样式及交互逻辑,直接修改原生 DOM 的 disabled 属性不会被 matInput 识别同步,同时 Angular 的数据绑定逻辑也可能覆盖你对原生属性的修改,因此无法生效。
解决方案
修改 hasPermission 指令,兼容普通输入框和 matInput 两种场景:在构造器中注入可选的 MatInput 实例,优先通过 MatInput 提供的官方API修改禁用状态,降级场景再操作原生DOM即可。
修改后的完整指令代码如下:
import { Directive, Input, Optional, ChangeDetectorRef, ElementRef } from '@angular/core'; import { MatInput } from '@angular/material/input'; // 替换为你实际的AuthService导入路径 import { AuthService } from './auth.service'; @Directive({ selector: '[hasPermission]' }) export class HasPermissionDirective { @Input('hasPermission') permission: string; constructor( private el: ElementRef, public auth: AuthService, // 可选注入MatInput实例,非matInput元素不会报错 @Optional() private matInput: MatInput, private cdr: ChangeDetectorRef ) {} ngOnInit() { if (!this.auth.can(this.permission)) { this.disable(); // 触发变更检测,避免出现状态更新异常 this.cdr.markForCheck(); } } private disable() { // 优先处理matInput场景 if (this.matInput) { this.matInput.disabled = true; return; } // 降级处理普通原生输入框 this.el.nativeElement.disabled = true; } }
验证效果
修改后不需要调整原有调用方式,两种场景都可以正常生效:
- 普通输入框用法:
<input type="text" hasPermission="module:permission-name">
- 搭配matInput用法:
<mat-form-field> <input matInput hasPermission="module:permission-name"> </mat-form-field>
补充说明
如果业务场景中输入框本身已经绑定了 [disabled] 属性,可根据优先级调整逻辑,比如权限控制优先级最高,直接覆盖原有绑定的禁用状态即可。
内容的提问来源于stack exchange,提问作者Free Mind
相关产品推荐
相关产品推荐

