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
相关产品推荐
相关产品推荐

