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();
}
}
我有反应形式
<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();
}
}