You need to enable JavaScript to run this app. Angular Material多选下拉框搜索功能实现及已选值丢失解决
优惠活动
大模型
产品
解决方案
定价
更多

Angular Material多选下拉框搜索功能实现及已选值丢失解决

问题核心原因
  • 搜索逻辑直接用过滤结果覆盖渲染mat-option的可选项数组,当已选中的选项不匹配当前搜索关键词时,对应的mat-option会从DOM移除。Angular Material多选组件的选中值展示,依赖已渲染的mat-option节点提取显示文本,没有对应节点时哪怕formControl里保留了选中值,也无法在触发器位置展示,给人“选中项消失”的错觉。
  • 现有代码存在语法错误(toLowerCase()后多余的点)、模板引用变量和TS取值不匹配的问题,会进一步干扰正常运行逻辑。

TS层调整

  • 拆分两个独立数组:_provider存储从接口加载的全量提供商数据,仅做读取不修改;provider存储当前渲染用的过滤后列表,承担mat-option的数据源。
  • 重写搜索过滤逻辑:过滤结果合并两部分内容——① 匹配当前输入关键词的选项;② 所有已被选中的选项(即使不匹配搜索关键词),去重后赋值给渲染列表,保证已选中的选项始终存在对应的mat-option节点。
  • 通过@ViewChild绑定模板上的搜索输入框变量,修正原有语法错误。

调整后的TS参考代码:

// 类成员定义
provider: any[] = [];
_provider: any[] = []; // 全量数据,接口加载完成后赋值,不做覆盖修改
providers = new FormControl<string[]>([]);

// 绑定模板上的#multiUserSearch输入框
@ViewChild('multiUserSearch') multiUserSearchInput!: ElementRef<HTMLInputElement>;

onInputChange() {
  const searchInput = this.multiUserSearchInput.nativeElement.value?.toLowerCase().trim() || '';
  const selectedValues = this.providers.value || [];

  // 匹配搜索关键词的选项
  const matchedByKeyword = this._provider.filter(item => 
    item.PROV.toLowerCase().includes(searchInput)
  );
  // 已选中但不在当前搜索结果里的选项,单独保留
  const selectedOutOfKeyword = this._provider.filter(item => 
    selectedValues.includes(item.PROV) && !item.PROV.toLowerCase().includes(searchInput)
  );

  // 合并两类结果,无重复
  this.provider = [...matchedByKeyword, ...selectedOutOfKeyword];
}

模板层调整

  • 优化mat-select-trigger的展示逻辑,直接输出表单值数组会显示为原始数组格式,拼接为逗号分隔的字符串提升可读性。
  • 保持组件结构符合Angular Material的交互规范,避免输入框的默认事件影响下拉框收起逻辑。

调整后的HTML参考代码:

<mat-form-field appearance="fill">
  <mat-label>Providers</mat-label>
  <mat-select multiple [formControl]="providers">
    <mat-select-trigger>
      {{ providers.value?.join(', ') || '' }}
    </mat-select-trigger>
    <input 
      type="text" 
      autocomplete="off" 
      matInput 
      placeholder="Search By Provider" 
      #multiUserSearch 
      (input)="onInputChange()">
    <mat-option *ngFor="let item of provider" [value]="item.PROV">
      {{ item.PROV }}
    </mat-option>
  </mat-select>
</mat-form-field>

补充优化建议

  • 初始化加载完全量_provider后,直接将全量数据赋值给provider作为初始渲染值,避免初始状态下拉框为空。
  • 针对数据量较大的场景,给输入监听增加防抖逻辑,减少高频过滤计算带来的性能损耗。
  • 可在搜索输入框上增加点击冒泡阻断逻辑,避免用户点击输入框时误触发下拉框收起。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 16:45:03