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

mat-chip-grid结合FormArray使用时的错误提示显示问题

解决Mat-Chip-Grid结合FormArray的错误提示不显示问题

核心问题分析

你遇到的问题根源在于:

  1. mat-form-field默认只关联单个FormControl的错误状态,不会自动识别FormArray的有效性
  2. 你给输入框加的required是针对单个输入的校验,而非要求FormArray至少包含一个元素
  3. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 06:45:33