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
相关产品推荐
相关产品推荐

