Angular多字段多选下拉列表过滤功能实现问题咨询
Angular 多选嵌套数组联合筛选实现
首先先修正一个模板笔误:你表格中渲染属性列时遍历的是item.property,但原始数据里的字段名是properties,不修正的话属性列无法正常渲染。
核心实现思路
- 单独存储全量原始数据,不要直接在渲染用的列表上做筛选,避免筛选后原始数据丢失无法恢复
- 筛选规则遵循:
- 不同筛选项之间取交集(AND逻辑):必须同时满足所有设置了筛选值的维度要求
- 同个筛选项的多选值取并集(OR逻辑):只要命中同维度下任意一个选中值就算匹配
- 某个筛选项没有选值时,跳过该维度的过滤
具体代码实现
1. 组件类新增全量数据存储
在组件中声明变量存放未经过滤的原始列表,初始化数据时同步赋值:
// 原始全量数据备份 originalList: Array<{ id: number; title: string; city: string; types: Array<{id: number, name: string}>; properties: Array<{id: number, name: string}>; }> = []; // 列表初始化逻辑(替换成你实际的接口请求/数据赋值逻辑) initListData() { // 拿到原始数据后同时存到备份变量和渲染变量 this.originalList = [/* 你的原始myList数据 */]; this.myList = structuredClone(this.originalList); }
2. 实现filterSet筛选函数
filterSet() { // 获取三个筛选项的选中值,空值兜底为空数组 const selectedCities = this.filterForm.get('filterCity')?.value ?? []; const selectedTypes = this.filterForm.get('filterAdType')?.value ?? []; const selectedProperties = this.filterForm.get('filterProperty')?.value ?? []; this.myList = this.originalList.filter(item => { // 城市维度匹配:未选城市直接放行,选中则判断当前项城市是否在选中列表内 const isCityMatch = selectedCities.length === 0 ? true : selectedCities.includes(item.city); // 类型维度匹配:未选类型直接放行,选中则判断嵌套types数组是否有任意一项name命中选中值 const isTypeMatch = selectedTypes.length === 0 ? true : item.types.some(type => selectedTypes.includes(type.name)); // 属性维度匹配:未选属性直接放行,选中则判断嵌套properties数组是否有任意一项name命中选中值 const isPropMatch = selectedProperties.length === 0 ? true : item.properties.some(prop => selectedProperties.includes(prop.name)); // 三个维度同时匹配才保留当前项 return isCityMatch && isTypeMatch && isPropMatch; }); }
3. 实现clearFilters清空函数
clearFilters() { // 重置表单所有选中值 this.filterForm.reset(); // 渲染列表恢复为全量原始数据 this.myList = structuredClone(this.originalList); }
4. 修正模板笔误
把属性列的遍历字段从item.property改为item.properties:
<td> <div *ngFor="let prop of item.properties"> {{prop.name}} </div> </td>
补充说明
- 如果需要筛选值变化后实时触发筛选,不需要点按钮,可以监听表单的
valueChanges事件,在回调里执行上面的筛选逻辑即可 - 如果需要调整匹配规则,比如同个筛选项多选需要同时命中所有选中值,把
some方法换成every方法即可 - 用
structuredClone做深拷贝是为了避免筛选操作修改原始嵌套数组里的对象引用,如果你的环境不支持这个API,可以换成展开运算符或者其他深拷贝方案
内容的提问来源于stack exchange,提问作者Svensen
相关产品推荐
相关产品推荐

