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

Angular中ng-drag-drop多列表拖拽:如何删除源列表项?

解决ng-drag-drop多列表拖拽时无法识别源列表的问题

我明白你现在遇到的问题了——三个列表之间拖拽时,因为没法知道被拖拽项来自哪个列表,导致删除操作总是错删到其他列表里。其实解决思路很简单:给拖拽数据额外带上源列表的标识,这样在drop事件里就能明确知道该从哪个列表移除项了。

下面是具体的修改步骤:

1. 修改HTML中的拖拽数据绑定

每个draggable元素的dragData不再只传item本身,而是传一个包含item和源列表标识的对象,这样就能在drop时拿到来源信息:

<div class="columnBox" droppable [dragOverClass]="'drag-target-border'" [dragHintClass]="'drag-hint'" (onDrop)="onListADrop($event)">
  <div class="task" *ngFor="let item of listA" draggable [dragClass]="'drag-over'" [dragData]="{item: item, source: 'A'}">
    {{ item.name }}
  </div>
</div>
<div class="columnBox" droppable [dragOverClass]="'drag-target-border'" [dragHintClass]="'drag-hint'" (onDrop)="onListBDrop($event)">
  <div class="task" *ngFor="let item of listB" draggable [dragClass]="'drag-over'" [dragData]="{item: item, source: 'B'}">
    {{ item.name }}
  </div>
</div>
<div class="columnBox" droppable [dragOverClass]="'drag-target-border'" [dragHintClass]="'drag-hint'" (onDrop)="onListCDrop($event)">
  <div class="task" *ngFor="let item of listC" draggable [dragClass]="'drag-over'" [dragData]="{item: item, source: 'C'}">
    {{ item.name }}
  </div>
</div>

2. 调整TypeScript的drop处理逻辑

在每个drop方法里,先从e.dragData中取出源列表标识和item,然后根据标识决定要删除的列表,同时修正你之前removeItem方法里的字段错误(你的数据里是name,但代码里用了title):

listA = [ {name: 'milk'}, {name: 'juice'} ];
listB = [ {name: 'beer'}, {name: 'water'} ];
listC = [ {name: 'wine'} ];

onListADrop(e: DropEvent) {
  const { item, source } = e.dragData;
  this.listA.push(item);
  this.removeItem(item, this.getSourceList(source));
}

onListBDrop(e: DropEvent) {
  const { item, source } = e.dragData;
  this.listB.push(item);
  this.removeItem(item, this.getSourceList(source));
}

onListCDrop(e: DropEvent) {
  const { item, source } = e.dragData;
  this.listC.push(item);
  this.removeItem(item, this.getSourceList(source));
}

// 根据源标识获取对应的列表
private getSourceList(source: string): Array<any> {
  switch(source) {
    case 'A': return this.listA;
    case 'B': return this.listB;
    case 'C': return this.listC;
    default: return [];
  }
}

removeItem(item: any, list: Array<any>) {
  // 这里把title改成name,和你的数据字段对应
  let index = list.map(function (e) { return e.name }).indexOf(item.name);
  if (index !== -1) { // 加个判断,避免index为-1时splice出错
    list.splice(index, 1);
  }
}

为什么这样有效?

原来的dragData只传递了item对象,没有任何来源信息,所以drop事件里没法区分它是从A、B还是C来的。现在我们给dragData增加了source字段,在drop时就能通过这个字段精准找到源列表,然后执行删除操作,就不会再出现错删的情况了。

另外我还帮你修正了removeItem里的字段错误(你数据里用的是name,但原代码写的是title),并且加了index的判断,防止找不到item时splice报错。

内容的提问来源于stack exchange,提问作者luke

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:42:52