web-dev-qa-db-ja.com

Angular 5 FormGroupリセットはバリデーターをリセットしません

ページにフォームがあり、FormGroup.reset()を呼び出すと、フォームクラスがng-pristine ng-untouchedに設定されますが、FormControl.hasError(...)は依然として真実を返します。ここで何が間違っていますか?

テンプレート

<form [formGroup]="myForm" (ngSubmit)="submitForm(myForm)">
  <mat-form-field>
    <input matInput formControlName="email" />
    <mat-error *ngIf="email.hasError('required')">
      Email is a required feild
    </mat-error>
  </mat-form-field>
  <mat-form-field>
    <input matInput type="password" formControlName="password" />
    <mat-error *ngIf="password.hasError('required')">
      Password is a required feild
    </mat-error>
  </mat-form-field>
  <button type="submit">Login</button>
</form>

コンポーネント

export class MyComponent {
  private myForm: FormGroup;
  private email: FormControl = new FormContorl('', Validators.required);
  private password: FormControl = new FormControl('', Validators.required);

  constructor(
    private formBuilder: FormBuilder
  ) {
    this.myForm = formBuilder.group({
      email: this.email,
      password: this.password
    });
  }

  private submitForm(formData: any): void {
    this.myForm.reset();
  }
}

プランカー

http://embed.plnkr.co/Hlivn4/

42
efarley

それ(FormGroup)は正しく動作します。フォームにはユーザー名とパスワードが必要です。したがって、フォームをリセットすると無効になります(ユーザー名/パスワードのないフォームは無効になります)。

私が正しく理解している場合、ここでの問題は、ページを最初にロードするときに(フォームが無効でもある)赤いエラーが表示されず、ボタンをクリックするとポップアップする理由です。この問題は、マテリアルを使用している場合に特に顕著です。

知る限り、<mat-error>FormGroupDirectiveではなくFormGroupの有効性を確認し、FormGroupをリ​​セットしてもFormGroupDirectiveはリセットされません。少し不便ですが、<mat-error>をクリアするには、FormGroupDirectiveもリセットする必要があります。

それを行うには、テンプレートで変数を次のように定義します。

<form [formGroup]="myForm" #formDirective="ngForm" 
  (ngSubmit)="submitForm(myForm, formDirective)">

そして、コンポーネントクラスで、formDirective.resetForm()を呼び出します。

private submitForm(formData: any, formDirective: FormGroupDirective): void {
    formDirective.resetForm();
    this.myForm.reset();
}

GitHubの問題: https://github.com/angular/material2/issues/419

86
Harry Ninh

コメントを読んだ後、これは正しいアプローチです

// you can put this method in a module and reuse it as needed
resetForm(form: FormGroup) {

    form.reset();

    Object.keys(form.controls).forEach(key => {
      form.get(key).setErrors(null) ;
    });
}

form.clearValidators()を呼び出す必要はありませんでした

12
Savio Rodrigues

Harry Ninhのソリューションに加えて、フォームボタンを選択せず​​にコンポーネントのformDirectiveにアクセスしたい場合:

テンプレート:

<form 
  ...
  #formDirective="ngForm" 
>

成分:

import { ViewChild, ... } from '@angular/core';
import { NgForm, ... } from '@angular/forms';

export class MyComponent {
 ...
 @ViewChild('formDirective') private formDirective: NgForm;

  constructor(... )

  private someFunction(): void { 
    ...
    formDirective.resetForm();
  }
}
10
Max

私も同じ問題を抱えていました。私の問題は、mat-form-fieldformGroupを使用していたことです。フォームをリセットした後、submittedフラグはリセットされませんでした。

だから、私のために働いた解決策は、ngFormのディレクティブをformGroupとともに配置し、onSubmit(form)を渡すことです。コンポーネントに@ViewChild('form') form;を追加し、this.form.resetForm();を使用しました

0
prisar

ResetForm()およびreset()を呼び出した後、submitがリセットされず、trueのままであるため、エラーメッセージが表示されることがわかりました。このソリューションは私のために働いた。入力タグでselect()およびfocus()を呼び出すソリューションを探しているときに見つけましたが、これも期待どおりに機能しませんでした。行をsetTimeout()でラップするだけです。それはちょっとしたハックですが、トリックを行います。

<form [formGroup]="myFormGroup" #myForm="ngForm">
    …
    <button mat-raised-button (click)="submitForm()">
</form>
submitForm() { 
    …
    setTimeout(() => {
        this.myForm.resetForm();
        this.myFormGroup.reset();
    }, 0);
}
0
Henri Fournier

フォームグループ内の特定のフォームコントローラーをリセットしようとすると、以下の解決策が役立ちます-

 this.myForm.get('formCtrlName').reset();
 this.myForm.get('formCtrlName').setValidators([Validators.required, Validators.maxLength(45), Validators.minLength(4), Validators.pattern(environment.USER_NAME_REGEX)]);
 this.myForm.get('formCtrlName').updateValueAndValidity();
0
Sayan Samanta