无法使用[formControlName]禁用matInput元素

时间:2018-01-25 20:17:22

标签: angular angular-material angular-material2

我在Angular组件中使用matInputmat-form-field(@ angular / material),我无法禁用matInput

A working example can be seen here.

我似乎错过了一些明显的东西,但对于我的生活,我无法弄清楚是什么。这是一个错误吗?

如果我从[formControlName]删除CustomFormInputComponent,那么我可以成功停用matInput

CustomFormInputComponent

import { Input, Component } from '@angular/core';
import { FormGroup } from '@angular/forms';

@Component({
  selector: 'app-custom-form-input',
  template: `
    <mat-form-field [formGroup]="form">
      <input matInput placeholder='Name' [formControlName]="formControlName" [disabled]='disabled'>
    </mat-form-field>
  `,
})
export class CustomFormInputComponent  {
  @Input() form: FormGroup;
  @Input() formControlName: string = 'name';
  @Input() disabled = false;
}

AppComponent

import { Component } from '@angular/core';
import { FormBuilder } from '@angular/forms';

@Component({
  selector: 'my-app',
  template: `
    <p>At least one of these inputs should be disabled, but none are :(</p>

    <app-custom-form-input [form]="form" [disabled]='true'></app-custom-form-input>

    <app-custom-form-input [form]="form" [disabled]="'disabled'"></app-custom-form-input>
  `,
})
export class AppComponent  {
  public form: any;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.form = this.fb.group({
      name: ''
    })
  }
}

非常感谢任何见解!

答案

有关David的答案的更多上下文:Angular根据被动表单控件的禁用状态更新DOM状态。我认为发生了什么:angular在CustomFormInputComponent之前渲染AppComponent并将组件渲染为禁用。然后渲染AppComponent,并在启用form控件的情况下构建name。然后Angular继续并取消禁用DOM输入元素(这是行为设计​​)。

7 个答案:

答案 0 :(得分:14)

如果您使用的是FormGroup,则不应禁用HTML模板中的表单。如果您尝试与FormControl一起禁用HTML,它将无法工作。相反,它应该在FormGroup中完成。试试这个:

  template: `
    <mat-form-field [formGroup]="form">
      <input matInput placeholder='Name' [formControlName]="formControlName">
    </mat-form-field>
  `

ngOnInit() {
    this.form = this.fb.group({
        name: new FormControl({ value: '', disabled: this.disabled })
    });
}

同样......不是什么大不了但你真的应该这样做:

public form: FormGroup;

而不是:

public form: any;

不要忘记导入

import { FormGroup, FormControl } from '@angular/forms';

顺便说一句,表单组声明中的名称应该与您在HTML中设置的内容相匹配。 所以:

<input formControlName="myInputName">

this.form = this.fb.group({
    myInputName....
});

答案 1 :(得分:1)

如果您使用的是材料,则可以添加

<mat-form-field [formGroup]="form">
  <input matInput placeholder='Name' [formControlName]="formControlName" readOnly>
</mat-form-field>

答案 2 :(得分:0)

如果使用的是FormGroup,则必须使用禁用的属性来创建FormGroup / FormControl:

name: new FormControl({ value: '', disabled: this.disabled })

但是,如果要禁用/启用,可以在HTML中使用它:

<input type="text" formControlName="name" [attr.disabled]="isDisabled == true ? true : null" />

答案 3 :(得分:0)

我遇到了同样的问题,并使用* ngIf指令解决了它。如果应禁用输入,请将其禁用,删除其表单绑定并手动提供其值。如果不是,那么请照原样使用formControl。

这是您的模板:

<mat-form-field [formGroup]="form">
  <input matInput placeholder='Name' [formControlName]="formControlName" [disabled]='disabled'>
</mat-form-field>

更改为:

<mat-form-field *ngIf="disabled">
  <input matInput placeholder='Name' [value]="form.formControlName" disabled='true'>
</mat-form-field>
<mat-form-field *ngIf="!disabled" [formGroup]="form">
  <input matInput placeholder='Name' [formControlName]="formControlName">
</mat-form-field>

答案 4 :(得分:0)

阅读本文的每个人都需要了解以下内容:

  1. Disable() 方法将从中删除该值。调试您的表单组,看看当您在输入上使用 .disable() 时会发生什么。您仍将拥有 FormControl,但该特定输入的值将消失。使用 enable()/disable() 时查看 FormGroup.value。

  2. 上面的只读答案是迄今为止实现禁用仍需要值的输入的最简单方法

  3. 结合使用 readonly 和 ngIf/ng-templates,您将能够成功切换已禁用的输入,并仍能在表单中捕获它的值。

  4. 在 DOM 中禁用响应式表单并不能像您想象的那样工作。

  5. 在 FormControl 创建期间禁用输入时,是否将禁用的属性绑定到稍后将尝试操作的变量并不重要。它仅在创建时拍摄该属性值的快照,并将禁用设置为控件上的布尔值。尝试随意操作该值,控件已经创建,无需关心新值是什么。

使用上述只读答案和 ng-templates 的示例:

<div class="col-4">
  <div *ngIf="hasVarHeight.checked else normalHeight">
    <mat-form-field>
      <mat-label>Height</mat-label>
      <input
        type="text"
        matInput
        [formControl]="heightCtrl"
        [value]="'*'" readonly>
    </mat-form-field>
  </div>
  <ng-template #normalHeight>
    <mat-form-field>
      <mat-label>Height</mat-label>
      <input
        type="text"
        matInput
        [formControl]="heightCtrl"
        mask="separator.3"
        thousandSeparator=","
        [suffix]="unitCtrl.value === 'Metric' ? ' mm' : ' in'"
        [placeholder]="unitCtrl.value === 'Metric' ? 'mm' : 'inches'"
        [dropSpecialCharacters]="false">
      <mat-error *ngIf="heightCtrl.hasError('required')">
        Height is required
      </mat-error>
    </mat-form-field>
  </ng-template>
</div>
</div>
<div class="form-row">
<div class="col-4">
  <mat-checkbox
    #hasVarHeight
    (click)="makeVariable('height')"
    name="varheight"
    [formControl]="hasVarHeightCtrl">
    Variable Height?
  </mat-checkbox>
</div>
</div>

希望以上内容能让您了解如何使用只读和模板使表单更好,同时仍保留所需输入的掩码。您可以使用上面的 makeVariable() 之类的方法在只读输入上动态设置一个值,并向用户展示一些有用的东西。

只是一个想法。感谢您对 Yogesh 的只读回答。

答案 5 :(得分:-1)

 <mat-form-field fxFlex>    
   <input matInput placeholder="No" formControlName="no" readonly>    
 </mat-form-field>

您是否尝试过只读选项。这对我来说很好。

工作代码: html:

 <mat-form-field fxFlex>    
   <input matInput placeholder="No" formControlName="no" readonly>    
 </mat-form-field>

答案 6 :(得分:-2)

在html页面中:

<form [formGroup]="formForAddDSBData">
              <mat-form-field class="form-element"  >
              <mat-icon matPrefix><i class="fa fa-address-card fa-1x"></i></mat-icon>
              <input matInput disabled id="AreaAddress" formControlName="AreaAddress" 
              #Contact1 placeholder="Area/Address" type="text" >
               <mat-error *ngIf="!formForAddDSBData.controls['AreaAddress'].valid && 
               formForAddDSBData.controls['AreaAddress'].touched">
                Area/Address is required
              </mat-error> 
      </mat-form-field>
</form>

要禁用此垫输入,您需要在.ts文件中编写以下代码

this.formForAddDSBData.get("AreaAddress").disable();