Angular 11 表格Order Pipe重置为0状态时无法恢复初始排序
问题原因
Array.sort()是原地操作方法,会直接修改调用该方法的数组本身的元素顺序。你之前的代码中升序、降序逻辑都是直接对传入的uploads数组调用sort,执行过一次排序后,原数组的顺序就已经被永久篡改,切回0状态时根本不存在未排序的原始数据,自然无法恢复初始顺序。这也是你直接返回原uploads数组依然是排序后状态的核心原因。- 现有逻辑在
colstat.value为0时没有做任何顺序重置处理,只是直接返回已经被修改过的数组,必然会保持上一次排序的结果。
修改方案
核心是在Pipe内部缓存初始顺序的数组副本,所有排序操作都基于这份缓存的副本执行,永远不直接修改原始输入数组和缓存的初始数据:
- 首次接收输入数组时,存一份浅拷贝作为初始顺序基准
- 排序状态为0时,直接返回初始基准数组的副本
- 执行升/降序排序时,先从初始基准数组拷贝一份新数组,再对新数组做排序,避免污染原始基准数据
修改后的可直接运行代码如下(适配Angular 11版本):
import { Pipe, PipeTransform } from '@angular/core'; import { ExternalUploads } from 'src/app/model/external/ExternalUploads '; @Pipe({ name: 'orderpipe', pure: false }) export class OrderPipe implements PipeTransform { // 缓存初始顺序的基准数组 private originalList: ExternalUploads[] = []; transform(uploads: ExternalUploads[], colstat: any) { // 首次加载或列表长度变化时,更新初始顺序缓存 if (uploads?.length && this.originalList.length !== uploads.length) { this.originalList = [...uploads]; } // 状态为0时返回初始顺序副本 if (colstat.value === 0) { return [...this.originalList]; } // 基于初始数组拷贝后再排序,不修改原始基准数据 const sortedList = [...this.originalList]; if (colstat.value === 1) { sortedList.sort((a, b) => a.name === b.name ? 0 : a.name < b.name ? -1 : 1); } else { sortedList.sort((a, b) => a.name === b.name ? 0 : a.name > b.name ? -1 : 1); } return sortedList; } }
补充说明
- 如果你的表格数据存在动态增删、替换的场景,需要调整初始缓存的更新判断逻辑(比如对比数组引用、元素唯一id),保证缓存的初始顺序和数据源的原始状态一致。
- 如果不需要Pipe自动追踪非输入参数的变更,可以将
pure设为true,在排序状态变更时手动触发数组引用更新,能获得更好的性能。
内容的提问来源于stack exchange,提问作者Xim_
相关产品推荐
相关产品推荐

