使用Angular CDK实现拖拽时如何保存已渲染DOM块的拖拽后位置
Angular CDK 拖拽位置丢失问题修复方案
核心思路
CDK拖拽的默认位置仅存在于组件实例内存中,数组重渲染时会重置,需要将位置信息持久化到你的blocks数组的每一项数据中,再通过CDK提供的输入属性绑定位置。
具体实现步骤
- 第一步:扩展你的block数据结构,新增两个存储偏移坐标的字段,示例类型定义:
interface BlockType { id: number | string; // 必须要有唯一不变的标识字段 x: number; // 存储拖拽后的x轴偏移,初始值为0 y: number; // 存储拖拽后的y轴偏移,初始值为0 // 其余你自己的业务字段 }
- 第二步:修改模板代码,绑定拖拽位置、监听拖拽结束事件、配置正确的trackBy:
<div *ngFor="let block of blocks; trackBy: trackByBlockId" cdkDrag [cdkDragFreeDragPosition]="{x: block.x, y: block.y}" (cdkDragEnded)="onDragEnded($event, block)" > </div>
- 第三步:在组件类中实现拖拽结束的回调和trackBy函数:
import { CdkDragEnd } from '@angular/cdk/drag-drop'; // 拖拽结束回调,更新当前块的存储坐标 onDragEnded(event: CdkDragEnd, block: BlockType) { const dragPosition = event.source.getFreeDragPosition(); block.x = dragPosition.x; block.y = dragPosition.y; } // trackBy函数,必须返回块的唯一标识,不能用数组索引 trackByBlockId(index: number, block: BlockType) { return block.id; }
注意事项
你之前trackBy不生效大概率是使用了数组索引作为返回值,数组增删时索引会发生变化,依然会触发全量重渲染,必须使用每个块独立的、不会变更的唯一id作为trackBy的返回值
调整完成后,位置信息直接绑定到你的业务数据上,无论数组增删还是页面重渲染,块都会自动恢复到之前拖拽的位置。
内容的提问来源于stack exchange,提问作者user15361861
相关产品推荐
相关产品推荐

