You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 06:09:53