使用响应式表单时禁用(使 read-only)mat-datepicker 上的文本输入

Disable (make read-only) text input on mat-datepicker when using a reactive form

我正在使用 Angular Material 2 的 mat-datepicker 并希望禁用输入元素,以便用户无法使用文本输入编辑值。

detailed instructions in the Angular Material 2 docs 关于如何禁用 mat-datepicker 的不同部分,但是,这些似乎没有涵盖如何在响应式表单的一部分时禁用文本输入。

Angular Material 文档建议您通过以下方式禁用文本输入:

<mat-form-field>
              // Add the disabled attribute to the input element ======
              <input disabled                          
                     matInput 
                     [matDatepicker]="dateJoined" 
                     placeholder="Date joined" 
                     formControlName="dateJoined">
              <mat-datepicker-toggle matSuffix [for]="dateJoined"></mat-datepicker-toggle>

              // Add [disabled]=false to the mat-datepicker =======
              <mat-datepicker [disabled]="false" 
                              startView="year"  
                              #dateJoined></mat-datepicker>
            </mat-form-field>

但是,如果您的日期选择器是反应式表单的一部分,文本元素将保持活动状态,您会从 Angular 收到以下消息:

It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true when you set up this control in your component class, the disabled attribute will actually be set in the DOM for you. We recommend using this approach to avoid 'changed after checked' errors. Example: form = new FormGroup({ first: new FormControl({value: 'Nancy', disabled: true})});

我更新了组件中的 FormGroup 以禁用 FormControl,这具有禁用输入的预期效果,但是,如果您随后获得 FormGroup 的值使用 this.form.value 禁用的表单控件不再存在。

是否有解决此问题的方法,它不涉及仅针对 mat-datepicker(s) 使用 ngModel 的单独模板驱动表单?

编辑: 将“read-only” 添加到 post 标题以澄清这与禁用控件无关 - 因为我问的是使输入元素read-only,但不禁用控制自身

创建一个残疾人FormControl真的很简单

1 - 不要在模板中使用禁用属性;

2 - 像这样实例化您的 FormGroup

this.formGroup = this.formBuilder.group({
  dateJoined: { disabled: true, value: '' }
  // ...
});

话虽这么说,虽然您想阻止用户在输入中输入内容,但您仍然希望通过单击按钮让他们 select 一个日期(更具体地说是 matSuffix),对吗?

如果正确,disable 不适用于这种情况,因为它会禁用所有输入(包括 matSuffix 中的按钮)。

要解决您的问题,您可以使用 readonly。正常实例化 FormGroup 然后在模板中实例化:

<input                          
  matInput 
  readonly <- HERE
  [matDatepicker]="dateJoined" 
  placeholder="Date joined" 
  formControlName="dateJoined">

DEMO

要扩展 developer033 的答案,动态切换 inputreadonly 状态,使用组件修改 readonly 属性变量。

动态切换只读

参见Stackblitz Demo

app.component.html

<input matInput 
  [readonly]="inputReadonly"   <!-- Update `readonly` property using variable -->
  [matDatepicker]="dateJoined" 
  placeholder="Date joined" 
  formControlName="dateJoined">

app.component.ts

import {Component} from '@angular/core';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import {VERSION} from '@angular/material';

@Component({
  selector: 'material-app',
  templateUrl: 'app.component.html'
})
export class AppComponent {
  formGroup: FormGroup;
  inputReadonly = true;
  version = VERSION;

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.formGroup = this.formBuilder.group({
      dateJoined: ''
    });
  }

  public toggleInputReadonly() {
    this.inputReadonly = !this.inputReadonly;
  }
}

这帮助我们禁用了输入:

<mat-form-field appearance="fill">
    <mat-label>Input disabled</mat-label>
    <input matInput [matDatepicker]="dp3" disabled>
    <mat-datepicker-toggle matSuffix [for]="dp3"></mat-datepicker-toggle>
    <mat-datepicker #dp3 disabled="false"></mat-datepicker>
</mat-form-field>

Ref