Angular Material表格清除过滤后子行数据源为空问题求助
问题解决思路
核心原因
JavaScript里对象、数组属于引用类型,你写的const filterdData = this.allData;只是把原数组的引用赋值给了变量,并没有复制新数据。主层级用filter()会返回全新数组,所以不会改动原allData;但处理子行时,你直接修改filterdData[index].subRows——这本质是在修改原allData里对应对象的subRows属性(因为它们指向同一块内存地址),导致过滤条件清空后,原数据的子行已经被改空,无法恢复。
修复方案
方案1:深拷贝原数据后操作
过滤前先对allData做深拷贝,确保操作的是完全独立的副本,不会影响原数据:
public filterDataSource(filters) { // 深拷贝原数据(适合无函数、Symbol等特殊类型的数据集) let filteredData = JSON.parse(JSON.stringify(this.allData)); // 主层级过滤 filteredData = filteredData.filter((x) => { return x.property.includes(filters.search); }); // 子层级过滤,操作副本不影响原数据 for(let index = 0; index < filteredData.length; index++) { filteredData[index].subRows = filteredData[index].subRows.filter((x) => { return x.property.includes(filters.search); }); } this.dataSource.data = filteredData; }
方案2:生成新对象处理子行(更高效)
如果不想深拷贝整个数组,可以在处理子行时为每个主对象创建新对象,只替换subRows属性,保留原对象的其他内容:
public filterDataSource(filters) { // 主层级过滤,返回新数组 let filteredData = this.allData.filter((x) => { return x.property.includes(filters.search); }); // 映射生成新对象,避免修改原数据的subRows filteredData = filteredData.map(item => { const filteredSubRows = item.subRows.filter(sub => sub.property.includes(filters.search)); // 展开运算符创建新对象,继承原属性并替换subRows return { ...item, subRows: filteredSubRows }; }); this.dataSource.data = filteredData; }
这个方案只复制需要修改的对象,性能更优,适合数据量较大的场景。
效果验证
修改后,清空过滤条件时,原allData的subRows会保持初始状态,过滤后的数据源会基于原数据重新生成,子行数据就能正常恢复。
内容的提问来源于stack exchange,提问作者Simon Damminga
相关产品推荐
相关产品推荐

