Angular CDK拖拽:获取拖拽项数据的问题求助
解决Angular CDK拖拽获取错误数据的问题
问题根源分析
- 泛型类型不匹配:你定义的
CdkDragDrop<string[]>泛型为string[],但实际ListData和UserList应为自定义对象数组,类型不匹配会导致数据读取异常。 - 拖拽项未绑定数据:源容器的
cdkDrag未显式绑定拖拽项数据,仅通过容器索引读取易因数据变化导致索引错位。 - 目标容器关联缺失:源容器与目标容器未通过
cdkDropListConnectedTo建立关联,可能导致拖拽上下文异常。
正确解决方案
1. 绑定拖拽项数据
在源容器的cdkDrag上添加[cdkDragData],直接绑定当前行的数据:
<tbody cdkDropList [cdkDropListData]="ListData"> <tr *ngFor="let list of ListData" cdkDrag [cdkDragData]="list"> <!-- 行内容 --> </tr> </tbody>
2. 修正drop函数的泛型与数据获取方式
通过event.item.data直接获取拖拽项的原始数据,无需依赖容器索引,同时修正泛型类型匹配实际数据结构:
// 假设你的列表项类型为ListItem,可根据实际定义替换 drop(event: CdkDragDrop<ListItem[], any[]>, userId: number) { // 直接获取拖拽的原始数据 const draggedItem = event.item.data; console.log('拖拽项数据:', draggedItem); // 后续逻辑:将拖拽项添加到对应用户的UserList中 const targetUser = this.userData.find(u => u.Id === userId); if (targetUser) { targetUser.UserList.push(draggedItem); // 可选:从源容器移除拖拽项 this.ListData.splice(event.previousIndex, 1); } }
3. 建立容器关联(可选但必要)
若拖拽跨容器需要生效,需给源容器和目标容器添加关联配置:
<!-- 源容器 --> <tbody #sourceList cdkDropList [cdkDropListData]="ListData" [cdkDropListConnectedTo]="userDropLists"> <tr *ngFor="let list of ListData" cdkDrag [cdkDragData]="list"> <!-- 行内容 --> </tr> </tbody> <!-- 目标容器 --> <li *ngFor="let user of userData"> <div #userDropList cdkDropList [cdkDropListData]="user.UserList" (cdkDropListDropped)="drop($event,user.Id)" cdkDropListSortingDisabled> <!-- 列表内容 --> </div> </li>
在组件类中通过ViewChildren获取所有目标容器引用:
import { ViewChildren, QueryList } from '@angular/core'; import { CdkDropList } from '@angular/cdk/drag-drop'; @ViewChildren('userDropList') userDropLists!: QueryList<CdkDropList>;
关键注意事项
- 必须通过
[cdkDragData]给拖拽项绑定数据,这是可靠获取拖拽内容的核心方式。 - 确保泛型类型与实际数据数组类型一致,避免类型转换错误。
- 跨容器拖拽必须配置
cdkDropListConnectedTo,否则目标容器无法识别拖拽事件。
内容的提问来源于stack exchange,提问作者user3653474
相关产品推荐
相关产品推荐

