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

Angular Material Autocomplete筛选失效及嵌套下拉自定义求助

解决Angular Material嵌套Select/Autocomplete的筛选与多选显示问题

我看到你在自定义Angular Material组件实现嵌套下拉时,遇到了筛选失效和多选显示格式的问题,下面分两部分给你针对性的解决方案:


一、修复搜索筛选功能

当前你的Autocomplete没有绑定过滤逻辑,需要添加实时筛选逻辑,让输入内容能匹配父组名称或子选项值:

1. 组件类添加筛选逻辑

在组件中新增过滤后的分组变量和筛选方法:

filteredStateList: typeof this.stateList = [...this.stateList];

filterStates(value: string) {
  const filterValue = value.toLowerCase().trim();
  // 同时过滤父组和子选项:匹配组名 或 组内有匹配的子项
  this.filteredStateList = this.stateList.map(group => ({
    ...group,
    // 过滤当前组内符合条件的子选项
    names: group.names.filter(name => 
      name.type.toLowerCase().includes(filterValue)
    )
  })).filter(group => 
    // 只保留有匹配内容的组
    group.letter.toLowerCase().includes(filterValue) || group.names.length > 0
  );
}

2. 模板绑定筛选触发事件

修改输入框,添加输入事件触发筛选:

<input type="text" matInput placeholder="Select Users" aria-label="Select Users" 
       [matAutocomplete]="auto" [formControl]="states"
       (input)="filterStates($event.target.value)">

3. 模板循环改为过滤后的列表

把原有的组循环替换成过滤后的列表:

<mat-optgroup *ngFor="let group of filteredStateList">
  <!-- 原有组内内容保持不变 -->
</mat-optgroup>

这样就能实现输入时同时匹配父组字母和子选项名称的筛选效果了。


二、优化多选后的显示格式

你当前的mat-select-trigger逻辑有小瑕疵,调整后可以完美实现Alaska (+2 others)的显示格式:

修改mat-select-trigger模板

<mat-select-trigger>
  {{ states.value?.length > 0 ? states.value[0] : '' }}
  <span *ngIf="states.value?.length > 1" class="example-additional-selection">
    (+{{ states.value.length - 1 }} {{ states.value.length === 2 ? 'other' : 'others' }})
  </span>
</mat-select-trigger>

简化选中逻辑(可选)

你的toggleSelection和toggleParent方法可以简化,避免冗余的stateRecord变量,直接通过states.value维护选中值:

toggleSelection(event: any, name: any, group: any) {
  let currentValues = this.states.value || [];
  if (event.checked) {
    currentValues = [...new Set([...currentValues, name.type])];
  } else {
    currentValues = currentValues.filter(val => val !== name.type);
  }
  this.states.setValue(currentValues);
  // 同步更新组的选中状态(判断是否所有子项都被选中)
  group.checked = group.names.every(item => currentValues.includes(item.type));
}

toggleParent(event: any, group: any) {
  let currentValues = this.states.value || [];
  const groupItemTypes = group.names.map((item: any) => item.type);
  if (event.checked) {
    currentValues = [...new Set([...currentValues, ...groupItemTypes])];
  } else {
    currentValues = currentValues.filter(val => !groupItemTypes.includes(val));
  }
  this.states.setValue(currentValues);
  // 同步更新组内子项的选中状态
  group.names.forEach((item: any) => item.checked = event.checked);
}

额外优化(可选)

如果希望页面加载时默认展开所有分组,可以在ngOnInit中初始化展开状态:

ngOnInit() {
  this.stateList.forEach(group => {
    this.isExpandCategory[group.letter] = true;
  });
}

完成以上修改后,你的嵌套下拉就能正常实现搜索筛选,并且多选时会显示符合预期的简洁格式了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 17:08:12