Angular中筛选功能实现方案优化咨询
Angular 多条件实时筛选优化方案
原代码问题分析
你的代码核心错误是:在category和materialType的筛选步骤中,错误地对已经是数组类型的filteredSet1/filteredSet2调用.set1/.set2属性,数组不存在这些属性,会直接触发运行时错误。此外,代码存在大量重复逻辑,可维护性差。
优化实现方案
方案1:修复错误并简化基础逻辑
先修正错误,同时简化初始化和筛选流程:
const result = { "set1" : [{"brand": "a", "category": "x", "materialType": 1},{"brand": "a", "category": "y", "materialType": 2}], "set2": [{"brand": "a", "category": "x", "materialType": 1},{"brand": "b", "category": "z", "materialType": 3}] }; // 初始化筛选结果为原始数据的副本,避免修改原数据 let filteredSet1 = [...result.set1]; let filteredSet2 = [...result.set2]; // 品牌筛选 if (selectedFilters.brand.length > 0) { filteredSet1 = filteredSet1.filter(item => selectedFilters.brand.includes(item.brand)); filteredSet2 = filteredSet2.filter(item => selectedFilters.brand.includes(item.brand)); } // 分类筛选 if (selectedFilters.category.length > 0) { filteredSet1 = filteredSet1.filter(item => selectedFilters.category.includes(item.category)); filteredSet2 = filteredSet2.filter(item => selectedFilters.category.includes(item.category)); } // 材质类型筛选 if (selectedFilters.materialType.length > 0) { filteredSet1 = filteredSet1.filter(item => selectedFilters.materialType.includes(item.materialType)); filteredSet2 = filteredSet2.filter(item => selectedFilters.materialType.includes(item.materialType)); } const finalResult = { set1: filteredSet1, set2: filteredSet2 };
方案2:抽象通用函数,提升可维护性
当数据集或筛选条件增多时,推荐抽象通用筛选逻辑,避免重复代码:
const result = { "set1" : [{"brand": "a", "category": "x", "materialType": 1},{"brand": "a", "category": "y", "materialType": 2}], "set2": [{"brand": "a", "category": "x", "materialType": 1},{"brand": "b", "category": "z", "materialType": 3}] }; // 通用筛选函数:对单个数据集应用所有筛选条件 const applyFilters = (dataSet, filters) => { return dataSet.filter(item => { // 无选中条件则默认通过,否则匹配对应字段 const brandMatch = filters.brand.length === 0 || filters.brand.includes(item.brand); const categoryMatch = filters.category.length === 0 || filters.category.includes(item.category); const materialMatch = filters.materialType.length === 0 || filters.materialType.includes(item.materialType); // 所有条件需同时满足 return brandMatch && categoryMatch && materialMatch; }); }; // 对所有数据集统一应用筛选 const finalResult = { set1: applyFilters(result.set1, selectedFilters), set2: applyFilters(result.set2, selectedFilters) };
Angular场景额外优化
若要实现实时响应筛选变更,可结合RxJS的可观察对象自动推导结果:
import { BehaviorSubject, map } from 'rxjs'; // 定义筛选条件的可观察对象,初始值为空筛选 selectedFilters$ = new BehaviorSubject<{brand: string[], category: string[], materialType: number[]}>({ brand: [], category: [], materialType: [] }); // 实时推导筛选后的结果,无需手动触发更新 filteredResult$ = this.selectedFilters$.pipe( map(filters => ({ set1: applyFilters(result.set1, filters), set2: applyFilters(result.set2, filters) })) ); // 模板中使用异步管道订阅,自动更新视图 // <div *ngFor="let dataset of filteredResult$ | async | keyvalue"> // <h3>{{ dataset.key }}</h3> // <div *ngFor="let item of dataset.value">{{ item | json }}</div> // </div>
内容的提问来源于stack exchange,提问作者Tony Roczz
相关产品推荐
相关产品推荐

