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

Angular Material mat-chip-list含输入框未显示验证错误问题

解决Mat-Chip-List必填验证错误不显示的问题

我来帮你搞定这个问题!Mat Chip List 默认不会自动和表单控件的验证状态关联起来,而且你需要确保表单控件的值和选中的 Chips 同步,还要正确配置错误提示的显示逻辑。下面是一步步的解决方案:

1. 修正表单控件的初始值与验证规则

首先,contactIds 用来存储选中联系人的 ID 数组,初始值应该设为空数组 [] 而非空字符串。另外,默认的 Validators.required 不会把空数组判定为无效,所以我们需要自定义一个验证器来确保至少选中一个联系人:

import { FormBuilder, FormGroup, Validators, AbstractControl, ValidationErrors } from '@angular/forms';
import { ENTER, COMMA } from '@angular/cdk/keycodes';

@Component({
  // 你的组件元数据
})
export class YourComponent {
  form: FormGroup;
  contacts: any[] = []; // 存储选中的联系人
  removable = true;
  separatorKeysCodes: number[] = [ENTER, COMMA]; // 新增chip的触发键
  addOnBlur = true;

  constructor(private formBuilder: FormBuilder) {
    this.form = this.formBuilder.group({
      name: ['', [Validators.required]],
      // 初始值为空数组,添加自定义验证器
      contactIds: [[], [Validators.required, this.minOneContactValidator.bind(this)]]
    });
  }

  // 自定义验证器:检查是否至少有一个联系人
  minOneContactValidator(control: AbstractControl): ValidationErrors | null {
    const selectedIds = control.value as number[];
    return selectedIds.length > 0 ? null : { minOneContact: true };
  }
}

2. 同步Chips操作与表单控件值

当添加或移除 Chip 时,必须同步更新 contactIds 表单控件的值,这样表单才能检测到状态变化并触发验证:

// 添加联系人Chip
addContact(event: MatChipInputEvent): void {
  const value = (event.value || '').trim();
  // 这里替换成你获取联系人的逻辑,比如从数据源匹配
  const matchedContact = /* 你的联系人匹配逻辑 */;
  
  if (matchedContact && !this.contacts.includes(matchedContact)) {
    this.contacts.push(matchedContact);
    // 更新表单控件为选中的ID数组
    this.form.get('contactIds')?.setValue(this.contacts.map(c => c.id));
  }
  
  event.chipInput!.clear();
}

// 移除联系人Chip
removeChipListItem(contact: any): void {
  const index = this.contacts.indexOf(contact);
  if (index >= 0) {
    this.contacts.splice(index, 1);
    // 更新表单控件值
    this.form.get('contactIds')?.setValue(this.contacts.map(c => c.id));
  }
}

3. 修正模板代码,绑定表单控件并显示错误

需要把 formControlName 绑定到 mat-chip-list,并添加 mat-error 来显示验证错误,同时要检查表单控件的状态(比如是否被触碰或表单已提交):

<form [formGroup]="form" (ngSubmit)="onSubmit()">
  <!-- Name输入框 -->
  <mat-form-field appearance="fill">
    <mat-label>Name</mat-label>
    <input matInput formControlName="name">
    <mat-error *ngIf="form.get('name')?.invalid && form.get('name')?.touched">
      Name is required
    </mat-error>
  </mat-form-field>

  <!-- Contacts Chip List -->
  <mat-form-field appearance="fill">
    <mat-label>Select Contacts</mat-label>
    <mat-chip-list #chipList formControlName="contactIds">
      <mat-chip 
        *ngFor="let contact of contacts" 
        [removable]="removable" 
        (remove)="removeChipListItem(contact)"
      >
        {{ contact.name | titlecase }}
        <mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
      </mat-chip>
      <!-- 用于添加新联系人的输入框 -->
      <input
        matInput
        [matChipInputFor]="chipList"
        [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
        [matChipInputAddOnBlur]="addOnBlur"
        (matChipInputTokenEnd)="addContact($event)"
        placeholder="Add a contact"
      >
    </mat-chip-list>
    <!-- 显示联系人必填错误 -->
    <mat-error *ngIf="form.get('contactIds')?.hasError('minOneContact') && (form.get('contactIds')?.touched || form.submitted)">
      At least one contact is required
    </mat-error>
  </mat-form-field>

  <button mat-raised-button color="primary" type="submit">Submit</button>
</form>

关键要点解释

  • 表单控件绑定:必须将 formControlName="contactIds" 绑定到 mat-chip-list,这样 Angular 才能把 Chip List 的状态和表单控件关联起来。
  • 值同步:每次添加/移除 Chip 都要更新 contactIds 的值,否则表单无法感知到选中状态的变化,验证规则不会触发。
  • 自定义验证器:默认的 Validators.required 不会把空数组判定为无效,所以需要自定义验证器检查数组长度。
  • 错误显示时机:mat-error 要结合控件的 touched 状态或表单的 submitted 状态,避免页面加载就显示错误。

内容的提问来源于stack exchange,提问作者Gloire

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:24:15