如何在Nz-Zorro Tree的nzOnDrop事件中撤销拖拽操作?
撤销Nz-Zorro Tree拖拽放置操作的实现方案
要在拖拽操作失败时撤销本次放置,核心思路是提前保存拖拽前的节点数据快照,当操作出错时恢复这个快照即可。具体实现步骤如下:
1. 监听拖拽开始事件,保存原始节点数据
首先在模板中添加nzOnDragStart事件,用于在拖拽开始时记录当前节点的完整状态(必须用深拷贝,避免引用类型导致原始数据被后续修改污染):
<nz-tree [nzTreeTemplate]="nzTreeTemplate" (nzOnDrop)="onNzOnDrop($event)" (nzOnDragStart)="onDragStart($event)" [nzData]="nodes" nzDraggable> </nz-tree> <ng-template #nzTreeTemplate let-node>...</ng-template>
2. 组件中实现快照保存与恢复逻辑
在组件类中维护一个变量存储原始节点数据,在拖拽开始时深拷贝当前节点,操作失败时重置回原始状态:
import { Component } from '@angular/core'; import { NzFormatEmitEvent } from 'ng-zorro-antd/tree'; @Component({ // 组件元数据 }) export class YourTreeComponent { nodes: any[] = []; // 你的树节点数据 private dragStartNodesSnapshot: any[] = []; // 拖拽开始时保存节点快照 onDragStart(event: NzFormatEmitEvent): void { // 深拷贝节点数据,JSON方法适合纯对象结构,若有特殊类型可改用lodash.cloneDeep this.dragStartNodesSnapshot = JSON.parse(JSON.stringify(this.nodes)); } onNzOnDrop(event: NzFormatEmitEvent): void { try { // 执行你的业务操作(比如节点移动、接口请求等) this.handleDropOperation(event); } catch (error) { // 操作失败,恢复到拖拽前的节点状态 this.nodes = JSON.parse(JSON.stringify(this.dragStartNodesSnapshot)); // 若Angular视图未自动更新,可注入ChangeDetectorRef手动触发变更检测 // this.cdr.detectChanges(); } } // 模拟业务操作,示例中抛出错误触发撤销逻辑 private handleDropOperation(event: NzFormatEmitEvent): void { // 这里写你的实际业务判断,比如节点层级校验、权限判断等 const isOperationValid = false; // 假设操作不合法 if (!isOperationValid) { throw new Error("拖拽操作不符合规则,执行撤销"); } // 操作合法时才更新节点数据 // ... 你的正常节点更新逻辑 } }
关键注意点
- 深拷贝的必要性:必须使用深拷贝保存快照,浅拷贝会导致原始数据随后续修改同步变化,无法实现恢复效果。如果节点包含函数、Date等特殊类型,建议使用
lodash.cloneDeep替代JSON方法。 - 变更检测:如果重置节点后Angular视图未更新,可注入
ChangeDetectorRef并调用detectChanges()手动触发视图刷新。 - 避免自动修改:Nz-Zorro Tree的拖拽交互不会自动修改
nzData,所有节点数据的变更都需要开发者手动处理,因此只要不执行合法的更新逻辑,或在出错时恢复快照,就能实现撤销效果。
内容的提问来源于stack exchange,提问作者Ashim
相关产品推荐
相关产品推荐

