ngx-charts日期范围过滤管道异常:扩大范围复用已过滤数组
问题分析
你碰到的核心问题是管道直接修改了原始数据里的引用类型属性,导致后续的过滤操作没办法基于初始的完整数据执行。
看你的DateInRangePipe代码,在transform方法里,你直接遍历传入的obj数组,还修改了每个data对象的series属性:
obj.forEach(data => { data.series = data.series.filter((item: any) => { return this.inRange(item.name, from, to); }); });
因为数组和对象都是引用类型,这里的修改会直接作用到原始的multi数组上。第一次缩小日期范围时,multi里的series已经被过滤过了;等你再扩大范围时,管道只能基于已经被剪过的series来处理,自然没法恢复之前被过滤掉的数据。
解决方案
核心思路是绝对不修改原始数据,每次都返回全新的对象和数组副本,这样不管多少次过滤,都是基于最开始的原始数据操作。修改后的管道代码如下:
export class DateInRangePipe implements PipeTransform { transform(obj: any[], from: Date, to: Date): any[] { if (!obj || !from || !to) { // 参数不全时,返回原始数组的副本,避免影响原数据 return [...obj]; } // 用map生成新数组,不碰原数组 return obj.map(data => { // 过滤series,得到新的数组 const filteredSeries = data.series.filter((item: any) => { return this.inRange(item.name, from, to); }); // 返回新的对象,保留原数据的其他属性,只替换series return { ...data, series: filteredSeries }; }); } inRange(date: Date, from: Date, to: Date): boolean { return date.getTime() >= from.getTime() && date.getTime() <= to.getTime(); } }
关键改动说明
- 用
map替代forEach:map会返回全新的数组,完全不会修改原始数组 - 创建对象副本:通过
{...data}展开原对象生成新实例,彻底避免修改原始的data对象 - 过滤后的
series只赋值给新对象:保证原始数据的series属性从头到尾都不受影响 - 增加边界校验:参数不全时返回原数组副本,避免出现意外报错
这么改完之后,每次管道执行都会基于原始的multi数组生成新的过滤结果,不管你是缩小还是扩大日期范围,都能得到正确的数据。
内容的提问来源于stack exchange,提问作者Withtaker
相关产品推荐
相关产品推荐

