如何使用自定义指令使材料<input matInput>变为只读?

问题描述

我想通过自己的自定义指令使使用材料<input>的{​​{1}}变为只读。伪指令matInput将用于基于安全标准设置只读。问题在于它可以在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>

请帮助如何使自定义指令与matInput配合使用?

编辑注意:由于指令是更简洁的代码,因此我不想从反应形式设置只读。我不想在组件中添加逻辑,我想在指令中使用逻辑,因为它是集中式的,并且将在所有形式中使用。

谢谢

解决方法

编辑:之前提供了禁用解决方案。 要使输入只读,请将逻辑移至“ 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-input,则由您的指令设置的readonly属性被Angular Material自己的readonly @Input覆盖。

在此处参考Mat-Input的源代码:Mat-Input Readonly @Input,以获取更多信息

因此,您可以做的是让代码执行设置属性的堆栈,并将其移交给事件循环。这样,您的代码将在Angular的操作之后执行。而最常见的实现方法是延迟时间为0秒的setTimeout

setTimeout(() => {
      this.elementRef.nativeElement.setAttribute('readonly',ro) 
    });

这是工作中的BLITZ