我想使用自定义指令使使用材质matInput
的<input>
变为只读。指令isControlReadonly
将用于根据安全标准设置只读。问题是它对<input>
有效,但对<input matInput>
没有影响
所以。。第一个输入有效,第二个无效:
<!-- this works -->
<input type="input" formControlName="test_field" isControlReadonly>
<!-- this doesn't works -->
<mat-form-field appearance="standard">
<mat-label>Name</mat-label>
<input matInput type="input" formControlName="customer_name" isControlReadonly>
</mat-form-field>
这是指令:
import { Directive, ElementRef, OnInit, ViewChildren } from '@angular/core';
import { SecurityService } from './security.service';
@Directive({selector: '[isControlReadonly]'})
export class IsReadonlyDirective implements OnInit {
constructor(
private elementRef: ElementRef,
private securityService: SecurityService
) { }
ngOnInit(): void {
var ro = !this.securityService.user.canEdit
this.elementRef.nativeElement.setAttribute('readonly', ro)
}
请帮助如何使自定义指令与matInput一起工作?
编辑注意:我不想从反应形式设置只读,因为指令是更干净的代码。我不想向我的组件添加逻辑,我希望在指令中使用逻辑,因为它是集中的,将在所有表单上使用。
感谢
EDIT:之前提供了禁用解决方案。要使输入只读,请将您的逻辑移动到"只读";ngAfterViewInit";以下是您指令的一个工作示例:
@Directive({selector: '[isControlReadonly]'})
export class IsReadonlyDirective implements OnInit, AfterViewInit {
constructor(
private elementRef: ElementRef,
private control: NgControl,
private securityService: SecurityService
) { }
ngAfterViewInit(): void {
var ro = !this.securityService.user.canEdit
this.elementRef.nativeElement.setAttribute('readonly', ro)
}
}
您的指令适用于所有类型的输入,但在mat输入的情况下,由指令设置的只读属性将被Angular Material自己的readonly
@input覆盖。
请参阅Mat Input的源代码:Mat Input Readonly@Input了解更多信息
所以,您可以做的是将设置属性的代码执行从堆栈中取出,并将其交给事件循环。这样,您的代码将在Angular的操作之后执行。最常见的实现方法是具有0秒延迟的setTimeout
setTimeout(() => {
this.elementRef.nativeElement.setAttribute('readonly', ro)
});
这是一个工作BLITZ