ページにフォームがあり、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();
}
}
プランカー
それ(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();
}
コメントを読んだ後、これは正しいアプローチです
// 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()
を呼び出す必要はありませんでした
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();
}
}
私も同じ問題を抱えていました。私の問題は、mat-form-field
とformGroup
を使用していたことです。フォームをリセットした後、submitted
フラグはリセットされませんでした。
だから、私のために働いた解決策は、ngForm
のディレクティブをformGroup
とともに配置し、onSubmit(form)
を渡すことです。コンポーネントに@ViewChild('form') form;
を追加し、this.form.resetForm();
を使用しました
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);
}
フォームグループ内の特定のフォームコントローラーをリセットしようとすると、以下の解決策が役立ちます-
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();