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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:56:42