Angular Material表单重置后mat-error仍显示的问题求助
问题描述
我使用Angular Material的FormControl创建了一个表单,提交后调用reset方法重置表单,并且调用markAllFieldsAsUntouched标记所有字段为未触碰状态,但表单仍会显示mat-error提示信息。以下是相关代码,恳请提供解决方法。
Component.html代码
<mat-form-field> <mat-label>Select a SO</mat-label> <input matInput placeholder="Select a SO" [formControl]="SOController" [matAutocomplete]="SOAuto"> <mat-autocomplete #SOAuto="matAutocomplete" (optionSelected)="onOptionSelectedSO($event)"> <mat-option *ngFor="let sO of filteredSO" [value]="sO.soName">{{sO.soName}}</mat-option> </mat-autocomplete> <div *ngIf="(SOController.touched) && (SOController.invalid)" class="text-danger"> <mat-error *ngIf="SOController.hasError('required')"><small>*SO Name is required</small></mat-error> </div> </mat-form-field> <mat-form-field> <mat-label>Select a Candidate</mat-label> <mat-select id="candidateId" name="candidateId" formControlName="candidateId"> <mat-option *ngFor="let candidate of CandidateData" value="{{candidate.candidateId}}"> {{candidate.candidateUid}}/{{candidate.candidateName}} </mat-option> </mat-select> <div *ngIf="(f.candidateId.touched) && (f.candidateId.invalid)" class="text-danger"> <mat-error *ngIf="f.candidateId.errors?.['required']"><small>*CandidateName is required</small></mat-error> </div> </mat-form-field> <button mat-raised-button color="primary" (click)="onSubmit()">Submit</button>
Component.ts代码
mapppingForm = new FormGroup({ candidateId: new FormControl('', [Validators.required]), sowId: new FormControl('', [Validators.required]), soName: new FormControl('', [Validators.required]), statusId: new FormControl('', [Validators.required]), mappingDate: new FormControl('', [Validators.required]) }) get f() { return this.mapppingForm.controls; } SOController = new FormControl('', [Validators.required]); filteredSO: any[] = []; onSubmit() { console.log(this.mapppingForm.value) this.mapppingForm.value.mappingDate = formatDate(this.mapppingForm.value.mappingDate as string, 'yyyy-MM-dd', this.locale); this.submitted = true; console.log(this.mapppingForm) if (this.mapppingForm.invalid) { this.markAllFieldsAsUntouched(); return; } else { console.log(this.mapppingForm) this.onAdd(); } } isFieldInvalid(fieldName: string): boolean { const control = this.mapppingForm.get(fieldName); return control !== null && control.invalid && (control.touched || this.submitted); } onAdd() { let formValue = this.mapppingForm.value; let obj = { sowId: formValue.sowId, candidateId: formValue.candidateId, StatusId: formValue.statusId, mappingDate: formValue.mappingDate, type: "post", }; this.service.PostCandidateMappingData(obj).subscribe(data => { console.log(data) this.openSnackBar(data, 'Ok') this.mapppingForm.reset(); this.SOController.reset(); this.markAllFieldsAsUntouched(); }) } markAllFieldsAsUntouched() { Object.keys(this.mapppingForm.controls).forEach(fieldName => { this.mapppingForm.controls[fieldName as keyof typeof this.mapppingForm.controls].markAsUntouched(); }); }
解决方法
1. 处理独立的FormControl
SOController是独立于mapppingForm的控件,当前的markAllFieldsAsUntouched方法仅处理了表单组内的控件,需要补充标记SOController为未触碰状态:
markAllFieldsAsUntouched() { Object.keys(this.mapppingForm.controls).forEach(fieldName => { this.mapppingForm.controls[fieldName].markAsUntouched(); }); // 新增:标记独立控件为未触碰 this.SOController.markAsUntouched(); }
2. 重置提交状态变量
onSubmit方法中设置了this.submitted = true,但重置表单时未将其重置为false,这可能导致错误提示逻辑异常,需在onAdd中补充:
onAdd() { // ... 原有请求代码 this.service.PostCandidateMappingData(obj).subscribe(data => { console.log(data) this.openSnackBar(data, 'Ok') this.mapppingForm.reset(); this.SOController.reset(); this.submitted = false; // 重置提交状态 this.markAllFieldsAsUntouched(); }) }
3. 可选:统一错误判断逻辑
建议使用已定义的isFieldInvalid方法(或新增针对独立控件的判断方法)来统一错误显示逻辑,避免模板中状态判断不一致:
- 针对
SOController新增判断方法:
isStandaloneFieldInvalid(control: FormControl): boolean { return control.invalid && (control.touched || this.submitted); }
- 修改模板中SO的错误判断:
<div *ngIf="isStandaloneFieldInvalid(SOController)" class="text-danger"> <mat-error *ngIf="SOController.hasError('required')"><small>*SO Name is required</small></mat-error> </div>
- 候选框的错误判断可直接使用现有方法:
<div *ngIf="isFieldInvalid('candidateId')" class="text-danger"> <mat-error *ngIf="f.candidateId.errors?.['required']"><small>*CandidateName is required</small></mat-error> </div>
4. 可选:标记字段为原始状态
如果上述方法仍未生效,可在重置时同时调用markAsPristine,将字段标记为未修改的原始状态:
this.mapppingForm.reset(); this.mapppingForm.markAsPristine(); // 新增 this.SOController.reset(); this.SOController.markAsPristine(); // 新增
内容的提问来源于stack exchange,提问作者Bellam Bharath
相关产品推荐
相关产品推荐

