Angular CDK:如何让cdkDropList内的元素支持拖拽移动?
解决方案
1. 补全画布元素的拖拽指令
cdkDragBoundary,缺少核心拖拽属性cdkDrag,这是元素无法拖拽的直接原因。修复后代码:
<app-widget-rect cdkDrag cdkDragBoundary=".svg-container" *ngFor="let artBoardWidge of artBoardWidges" ></app-widget-rect>
2. 适配自由拖拽场景(可选,适用于draw.io类任意位置摆放需求)
cdkDropList默认用于列表项上下排序,若需要实现画布内元素任意位置摆放,无需依赖默认排序逻辑,调整方案如下:
- 给Widget接口新增
x、y坐标字段,存储元素在画布中的位置 - 监听
cdkDragMoved事件实时更新元素坐标 - 给组件添加绝对定位样式绑定,通过坐标控制元素位置
示例代码:
// Widget 接口新增字段 interface Widget { // 原有字段 id: string; type: string; // 新增坐标字段 x: number; y: number; } // 拖拽移动事件处理 onDragMoved(event: CdkDragMove, widget: Widget) { const el = event.source.element.nativeElement; widget.x = event.pointerPosition.x - el.offsetWidth / 2; widget.y = event.pointerPosition.y - el.offsetHeight / 2; }
模板调整:
<div class="svg-container" style="position: relative;width:300px;height:300px;border-style: dotted;" > <app-widget-rect cdkDrag cdkDragBoundary=".svg-container" *ngFor="let widget of artBoardWidges" (cdkDragMoved)="onDragMoved($event, widget)" [style.position]="'absolute'" [style.left.px]="widget.x" [style.top.px]="widget.y" ></app-widget-rect> </div>
3. 修正左侧容器数据绑定
当前左侧容器的拖拽元素为硬编码静态节点,未遍历customWidgets数组,会导致复制元素时无法正确获取组件数据,调整为遍历渲染即可:
<div class="widget-container" cdkDropList [id]="'container'" [cdkDropListData]="customWidgets" [cdkDropListConnectedTo]="['artBoard']" > <div cdkDrag *ngFor="let widget of customWidgets"> <svg height="50" width="50"> <rect width="50" height="50" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" /> </svg> </div> </div>
依赖检查
确认所在模块已导入DragDropModule:
import { DragDropModule } from '@angular/cdk/drag-drop'; @NgModule({ imports: [ // 其他导入 DragDropModule ] }) export class YourModule { }
内容的提问来源于stack exchange,提问作者Heng-Shiou Sheu
相关产品推荐
相关产品推荐

