Angular项目drag-and-drop指令异常 输出undefined如何解决
问题根因
打印拖拽项名称返回undefined,本质是拖拽事件触发时,指令逻辑没有拿到正确的拖拽项上下文对象,常见触发场景有三个:
- 指令未定义输入属性接收模板传入的当前循环项,只能拿到原生事件对象,无法关联到对应业务数据
- 拖拽事件
dataTransfer存、取数据时key不匹配,或者未做序列化/反序列化处理,读取结果为null - 模板绑定拖拽项时作用域错误,比如
*ngFor循环外绑定了不存在的变量,实际传给指令的值本身就是undefined
修复步骤
- 给拖拽指令补充输入属性,用于接收模板传入的当前拖拽项数据:
// drag-and-drop.directive.ts import { Directive, Input, HostListener } from '@angular/core'; @Directive({ selector: '[appDragAndDrop]' }) export class DragAndDropDirective { // 接收模板传入的当前拖拽项 @Input() dragItem: { name: string, [key: string]: any }; @HostListener('dragstart', ['$event']) onDragStart(e: DragEvent) { // 序列化后存入dataTransfer,key使用固定值 e.dataTransfer.setData('dragItem', JSON.stringify(this.dragItem)); e.dataTransfer.effectAllowed = 'move'; } @HostListener('dragover', ['$event']) onDragOver(e: DragEvent) { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; } @HostListener('drop', ['$event']) onDrop(e: DragEvent) { e.preventDefault(); // 按相同key读取后反序列化 const droppedItem = JSON.parse(e.dataTransfer.getData('dragItem')); // 此时可正常获取name属性 console.log('拖拽项名称:', droppedItem.name); // 在此处编写列表排序、位置更新的业务逻辑即可 } }
- 修正模板绑定逻辑,
*ngFor循环渲染列表项时,把当前循环的item正确传给指令:
<!-- app.component.html --> <div class="list-container"> <div *ngFor="let item of itemList; let i = index" appDragAndDrop [dragItem]="item" [draggable]="true" class="list-item" > {{ item.name }} </div> </div>
避坑提醒:不要通过
(dragstart)传$event后从event.target的DOM属性上找业务数据,Angular的组件/指令属性默认不会渲染到DOM节点上,这种写法很容易拿到undefined,通过指令输入绑定上下文是最稳定的实现方式。
内容的提问来源于stack exchange,提问作者tjdwlshwp
相关产品推荐
相关产品推荐

