mat-chip-grid结合FormArray使用时的错误提示显示问题
解决Mat-Chip-Grid结合FormArray的错误提示不显示问题
核心问题分析
你遇到的问题根源在于:
mat-form-field默认只关联单个FormControl的错误状态,不会自动识别FormArray的有效性- 你给输入框加的
required是针对单个输入的校验,而非要求FormArray至少包含一个元素 errorStateMatcher被绑定到了mat-chip-grid上,而它应该绑定到mat-form-field才会生效
分步解决方案
1. 给FormArray添加自定义校验器
首先在组件中编写校验规则,确保FormArray至少有一个元素:
import { ValidatorFn, AbstractControl, ValidationErrors } from '@angular/forms'; // 自定义校验器:要求FormArray长度不小于指定值 minLengthValidator(minLength: number): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { const formArray = control as FormArray; return formArray.length >= minLength ? null : { minLength: { requiredLength: minLength, actualLength: formArray.length } }; }; }
创建FormArray时应用这个校验器:
this.form = this.fb.group({ values: this.fb.array([], this.minLengthValidator(1)) });
2. 修正ErrorStateMatcher的绑定和逻辑
将errorStateMatcher绑定到mat-form-field上,并让它检测FormArray的状态:
import { ErrorStateMatcher } from '@angular/material/core'; import { FormControl, FormGroupDirective, NgForm } from '@angular/forms'; errorStateMatcher: ErrorStateMatcher = { isErrorState: (control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean => { const valuesArray = this.form.get('values') as FormArray; // 当数组无效,且表单已提交或数组被触摸时触发错误提示 return !!valuesArray?.invalid && (valuesArray.touched || form?.submitted); } };
3. 调整模板代码
- 移除输入框的
required属性(我们要的是数组整体校验,不是单个输入) - 将
[errorStateMatcher]移到mat-form-field标签上 - 调整
mat-error的判断条件,匹配自定义校验的错误类型
修改后的模板:
<mat-form-field [errorStateMatcher]="errorStateMatcher"> <mat-label>Values</mat-label> <mat-chip-grid #chipGrid aria-label="Enter values" formArrayName="values"> <mat-chip-row *ngFor="let valueControl of form.controls.values.controls; let valueIndex = index" (removed)="removeValue(form.controls.values, valueIndex)" [editable]="true"> {{ valueControl.value }} <button matChipRemove [attr.aria-label]="'remove ' + valueControl.value"> <mat-icon>cancel</mat-icon> </button> </mat-chip-row> <input class="form-control" placeholder="New value..." [matChipInputFor]="chipGrid" [matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="true" (matChipInputTokenEnd)="addValue(form.controls.values, $event)"> </mat-chip-grid> <mat-error *ngIf="form.controls.values.hasError('minLength')">At least one value is required</mat-error> </mat-form-field>
4. 确保数组状态更新
在添加/移除元素的方法中,手动触发数组的有效性更新和触摸状态标记:
removeValue(formArray: FormArray, index: number) { formArray.removeAt(index); formArray.updateValueAndValidity(); formArray.markAsTouched(); } addValue(formArray: FormArray, event: MatChipInputEvent) { const value = (event.value || '').trim(); if (value) { formArray.push(this.fb.control(value)); } event.chipInput!.clear(); formArray.updateValueAndValidity(); }
内容的提问来源于stack exchange,提问作者devmiles.com
相关产品推荐
相关产品推荐

