Angular双拖拽列表加筛选后transferArrayItem索引错误移错项问题
Angular拖拽列表筛选后索引错位修复方案
根本原因:视图层渲染的是筛选后的子集数组,
transferArrayItem方法默认传入的是筛选后列表的索引,和原始数组的索引无法对应,导致移动的条目和选中条目不一致。
修复步骤
- 拆分数据源,分别维护「原始数据数组」和「筛选后展示数组」,不要直接修改原始数组用于筛选渲染;给所有列表项设置唯一id属性,放弃依赖索引定位条目。
- 绑定
cdkDragStarted事件,拖拽开始时直接记录当前拖拽项的唯一id,而非依赖事件返回的索引:
模板代码示例:
对应逻辑代码:<div cdkDrag *ngFor="let item of filteredList1" (cdkDragStarted)="recordDragItem(item.id, 1)"> {{ item.name }} </div>// 存储当前拖拽的条目实例 currentDragItem: any; recordDragItem(id: number, listNo: 1 | 2) { const sourceList = listNo === 1 ? this.originList1 : this.originList2; this.currentDragItem = sourceList.find(i => i.id === id); } - 重写
drop事件逻辑,移动条目时先查找到拖拽项在原始数组的真实索引,再调用transferArrayItem:drop(event: CdkDragDrop<any[]>) { if (event.previousContainer === event.container) { moveItemInArray(event.container.data, event.previousIndex, event.currentIndex); // 同列表排序后重新触发筛选刷新视图 this.refreshFilterList(); return; } // 查找拖拽项在原始源列表的真实索引 const sourceOriginList = event.previousContainer.data; const realPrevIndex = sourceOriginList.findIndex(i => i.id === this.currentDragItem.id); // 用真实索引执行移动 transferArrayItem(sourceOriginList, event.container.data, realPrevIndex, event.currentIndex); // 移动完成后刷新两个列表的筛选结果 this.refreshFilterList(); } - 单独封装
refreshFilterList方法,每次输入搜索关键词、完成拖拽操作后触发,基于最新的原始数组生成筛选后的展示数组。
内容的提问来源于stack exchange,提问作者Sarahbe
相关产品推荐
相关产品推荐

