web-dev-qa-db-ja.com

リアクティブフォームを使用する場合、mat-datepickerでのテキスト入力を無効にします

Angular Material 2のmat-datepickerを使用していますが、ユーザーがテキスト入力を使用して値を編集できないようにinput要素を無効にします。

Angular Material 2 docsの詳細な手順mat-datepickerのさまざまな部分を無効にする方法がありますが、一部であるときにテキスト入力を無効にする方法については説明していませんリアクティブフォームの。

Angular Material docsでは、次の方法でテキスト入力を無効にすることを推奨しています。

<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から次のメッセージが表示されます。

リアクティブフォームディレクティブでdisabled属性を使用しているようです。コンポーネントクラスでこのコントロールを設定するときにdisabledをtrueに設定すると、実際にはDOMでdisabled属性が設定されます。 「チェック後の変更」エラーを回避するために、このアプローチを使用することをお勧めします。例:form = new FormGroup({first:new FormControl({value: 'Nancy'、disabled:true})});

コンポーネントのFormGroupを更新してFormControlを無効にしました。これにより、this.form.valueを使用してFormGroupの値を取得した場合に、入力を無効にするという望ましい効果が得られます。無効化されたフォームコントロールはもう存在しません。

この問題の回避策は、mat-datepicker(s)だけにngModelを使用する別のテンプレート駆動フォームを持たないことですか?

15
nclarx

無効なFormControlを作成するのは本当に簡単です。

1-テンプレートでdisabled属性を使用しないでください。

2-次のようにFormGroupをインスタンス化します。

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

そうは言っても、ユーザーが入力に何かを入力できないようにしたいのですが、ボタン(具体的にはmatSuffix)をクリックして日付を選択できるようにしますか?

正しい場合、disableはすべての入力(matSuffixのボタンを含む)を無効にするため、この場合は機能しません。

ケースを解決するには、readonlyを使用できます。 FormGroupを通常にインスタンス化してから、テンプレートでインスタンス化します。

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

DEMO

42
developer033

developer0 の答えを展開し、readonlyinput状態を動的に切り替えるには、コンポーネント変数を使用して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;
  }
}
1