Angular 12表单字段初始化触发required必填错误问题
问题触发原因
Angular响应式表单初始化时,若字段默认值为空,绑定的required校验器会直接将字段状态标记为INVALID。而Angular Material的mat-error组件默认只要对应字段校验不通过就会展示,因此会出现页面刚加载就显示必填错误的问题。
解决方案
方案1:在mat-error上手动添加展示条件
直接在模板中为mat-error绑定*ngIf判断,仅当字段被交互过(触碰/修改)或表单已提交时才展示错误:
<form [formGroup]="yourForm" (ngSubmit)="submitForm()"> <mat-form-field> <mat-label>字段名称</mat-label> <input matInput formControlName="yourField"> <mat-error *ngIf="yourForm.get('yourField')?.hasError('required') && (yourForm.get('yourField')?.touched || yourForm.get('yourField')?.dirty || yourForm.submitted)"> 此字段为必填项 </mat-error> </mat-form-field> <button type="submit">提交</button> </form>
说明:
touched:字段已失焦过dirty:字段值被用户修改过submitted:表单已触发过提交操作
方案2:自定义ErrorStateMatcher全局/局部统一控制(更推荐)
Angular Material提供了ErrorStateMatcher用于统一控制错误提示的触发逻辑,无需在每个mat-error上重复写判断条件。
第一步:定义自定义匹配器
import { ErrorStateMatcher } from '@angular/material/core'; import { FormControl, FormGroupDirective, NgForm } from '@angular/forms'; export class InteractionOnlyErrorMatcher implements ErrorStateMatcher { isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean { const formSubmitted = !!form?.submitted; return !!(control?.invalid && (control?.touched || control?.dirty || formSubmitted)); } }
第二步:配置匹配器
局部生效(仅当前组件使用)
在组件类中声明匹配器实例:
export class YourFormComponent { errorMatcher = new InteractionOnlyErrorMatcher(); yourForm = new FormGroup({ yourField: new FormControl('', [Validators.required]) }); }
在模板中给对应输入框绑定匹配器:
<input matInput formControlName="yourField" [errorStateMatcher]="errorMatcher"> <mat-error>此字段为必填项</mat-error>
全局生效(所有表单默认使用)
在根模块AppModule中全局注入匹配器:
// app.module.ts import { NgModule } from '@angular/core'; import { ErrorStateMatcher } from '@angular/material/core'; import { InteractionOnlyErrorMatcher } from './custom-error-matcher.ts'; @NgModule({ providers: [ { provide: ErrorStateMatcher, useClass: InteractionOnlyErrorMatcher } ] }) export class AppModule {}
配置后所有mat-error默认都会遵循该逻辑,无需额外绑定。
内容的提问来源于stack exchange,提问作者Ozzott
相关产品推荐
相关产品推荐

