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

Mat-chip-list添加/变更选项时调用函数的问题

解决Mat Chip List添加/内容变更时调用指定函数的问题

看起来你已经搞定了移除Chip的逻辑,现在需要在添加Chip或者Chip列表内容变更时触发自定义方法对吧?之前尝试的(click)和(selectionChanged)不生效是因为用错了事件或者时机不对,我给你几个针对性的解决方案:


一、针对「通过自动补全添加Chip」的场景

你已经在mat-autocomplete上用了(optionSelected)事件,只需要在对应的selected()方法里,完成Chip添加后立刻调用你的目标函数就行,还能直接把最新的列表传进去:

组件类代码修改

selected(event: MatAutocompleteSelectedEvent): void {
  const sector = event.option.value;
  // 避免重复添加
  if (!this.chosenSectors.find(s => s.service_code === sector.service_code)) {
    this.chosenSectors.push(sector);
    // 调用你的自定义方法,传入当前最新的chosenSectors
    this.testMethod([...this.chosenSectors]); // 用扩展运算符传副本,避免引用问题
  }
  this.sectorCtrl.setValue('');
}

二、针对「手动输入Blur/回车添加Chip」的场景

你设置了matChipInputAddOnBlur="true",意味着输入框失焦时会尝试添加Chip,但这个动作不会自动触发你的方法,需要绑定matChipInputTokenEnd事件来捕获:

模板代码修改

给<input>标签添加事件绑定:

<input 
  placeholder="Sectors" 
  #sectorInput 
  [formControl]="sectorCtrl" 
  [matAutocomplete]="auto" 
  [matChipInputFor]="chipList" 
  [matChipInputAddOnBlur]="true"
  (matChipInputTokenEnd)="addSectorFromInput($event)" <!-- 新增这个事件 -->
>

组件类添加处理方法

addSectorFromInput(event: MatChipInputEvent): void {
  const inputValue = (event.value || '').trim();
  if (!inputValue) return;

  // 这里根据输入值匹配对应的sector(比如从你的filteredSectors里查找)
  this.filteredSectors.subscribe(sectors => {
    const matchedSector = sectors.find(s => 
      s.service.includes(inputValue) || s.service_code.includes(inputValue)
    );
    if (matchedSector && !this.chosenSectors.find(s => s.service_code === matchedSector.service_code)) {
      this.chosenSectors.push(matchedSector);
      // 调用自定义方法
      this.testMethod([...this.chosenSectors]);
    }
  });

  // 清空输入框
  event.chipInput.clear();
  this.sectorCtrl.setValue('');
}

三、监听整个Chip列表的变更(通用方案)

如果你的chosenSectors可能在其他地方被修改(比如异步更新、批量操作),可以用RxJS的BehaviorSubject来监听数组的所有变化,一有变动就自动调用方法:

组件类改造

import { BehaviorSubject } from 'rxjs';

// 用BehaviorSubject包裹chosenSectors
private chosenSectors$ = new BehaviorSubject<any[]>([]);

ngOnInit(): void {
  // 订阅列表变化,自动触发testMethod
  this.chosenSectors$.subscribe(updatedSectors => {
    this.testMethod(updatedSectors);
  });
}

// 以后修改列表时,不要直接操作chosenSectors数组,而是调用next更新
addSector(sector: any): void {
  const current = this.chosenSectors$.value;
  if (!current.find(s => s.service_code === sector.service_code)) {
    this.chosenSectors$.next([...current, sector]);
  }
}

removeSector(sector: any): void {
  const current = this.chosenSectors$.value;
  const updated = current.filter(s => s.service_code !== sector.service_code);
  this.chosenSectors$.next(updated);
}

模板修改

把*ngFor的数据源换成chosenSectors$ | async:

<mat-chip *ngFor="let sector of chosenSectors$ | async" [removable]="true" (removed)="removeSector(sector)">
  {{ sector.service_code + ": " + sector.service }}
  <mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>

为什么之前的方法不生效?

  • (click):绑定在mat-chip-list上的话,点击区域就会触发,但时机不对——比如点击自动补全选项时,点击事件会在Chip添加前触发,拿不到最新值。
  • (selectionChanged):这是mat-selection-list(选择列表)的专属事件,mat-chip-list根本不支持这个事件,所以完全不会触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:13:43