Angular 响应式表单提交并清除验证

Angular Reactive Form submit and clear validation

我有反应形式

 <form [formGroup]="secondFormGroup">
      <ng-template matStepLabel>enter items</ng-template>
      <div style="display: flex; flex-direction: column;">
        <mat-form-field>
          <input matInput type="text" placeholder="category"  [(ngModel)]="newItem.CategoryName" formControlName="category"
          />
        </mat-form-field>
        <mat-form-field>
          <input matInput type="text" placeholder="sub category"  [(ngModel)]="newItem.SubCategoryName" formControlName="subCategory"
          />
        </mat-form-field>
        <mat-form-field>
          <input matInput type="text" placeholder="product"  [(ngModel)]="newItem.ProductName" formControlName="name"/>
        </mat-form-field>
        <mat-form-field>
          <input matInput  [(ngModel)]="newItem.Amount" type="number" min="0" placeholder="amount" formControlName="amount"
          />
        </mat-form-field>
        <mat-form-field>
          <input matInput  [(ngModel)]="newItem.Price" type="number" min="0" placeholder="price" formControlName="price"
          />
        </mat-form-field>
        <button mat-raised-button color="primary" (click)="AddNewProduct(newItem)" style="float: left; align-self: flex-end;">submit</button>
      </div>
    </form>

我是这样初始化的:

 this.secondFormGroup = this._formBuilder.group({
  category: ['', Validators.required],
  subCategory: ['', Validators.required],
  name: ['', Validators.required],
  amount: ['', Validators.required],
  price: ['', Validators.required]
});

单击 sumbit 后,我​​调用此方法:

AddNewProduct(newProduct) {
if (this.secondFormGroup.valid) {
  //add product
  this.secondFormGroup.reset();
 } 
}

添加产品后,我清除了表单。 但是,一旦表单被清除,它就会触发验证错误。 我希望验证错误仅在用户单击提交且表单无效时显示,而不是在提交后清除表单时显示。

我该如何解决这个问题?

您可以使用 clearValidators()

轻松清除表单的 validators
this.secondFormGroup .clearValidators();
this.secondFormGroup .updateValueAndValidity();

但是这将从实际的表单组中删除验证器,并且它不会在下一次提交的表单上显示errors

更好的方法是:

您可以简单地在错误模板上使用标志,以显示基于表单 submit/reset 的错误。 set/reset 相应的标志。

public formSubmitted = false;

onSubmit(){
   this.formSubmitted = true;
}

reset(){
   this.formSubmitted = false;
}

模板文件

<div *ngIf="formSubmitted">
 display errors
</div>

如果您使用 Angular Material 输入,则可以通过将输入设置为 untouched 来隐藏错误状态。 Material 输入字段仅在触摸输入时显示错误状态。

所以

this.secondFormGroup.markAsUntouched();

应该可以解决问题。

您可能必须在此类操作后启动更改检测运行(取决于场景)

这里是概念验证。输入最初处于错误状态。专用按钮清除此状态,直到将来输入。

https://stackblitz.com/edit/angular-tadkmb?file=src%2Fapp%2Fapp.component.ts

问题似乎是调用重置后表单被标记为已提交。如果表单被标记为已提交,无论其是否原始,错误都将突出显示。

您需要调用 resetForm,它在 FormGroupDirective 上:

@ViewChild(FormGroupDirective) formGroupDirective: FormGroupDirective;

this.formGroupDirective.resetForm();

其次,您需要将其包装在超时为 0 的 setTimeout 中,以便在 重置表单之前 提交表单。

setTimeout(() => this.formGroupDirective.resetForm(), 0)

我已经在 StackBlitz 中对此进行了测试,似乎一切正常:

https://stackblitz.com/edit/angular-l6xq1d?file=src%2Fapp%2Fapp.component.ts

这有效,试试这个你需要重置 formDirective 否则它不会 100% 恢复表单

模板:

<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();
  }
}