import { injectable } from 'inversify'; import { UndoRedoRecord } from '../undoRedo'; import { OperateTypeEnum, OperatePositionEnum } from './types'; import { LinkedTree, LinkedTreeNode, IDisposable } from 'ts-toolset'; import { TreeDndDatasetUndoRedoActionPairsCollection } from './treeDatasetUndoRedo'; import { deepClone, getPartialProperty } from 'ts-toolset/dist/common/object'; export interface ITreeDataset extends IDisposable { /** 数据操作 */ operate(type: OperateTypeEnum, position: OperatePositionEnum, source: LinkedTreeNode, target?: LinkedTreeNode): void; /** 获取撤销恢复记录 */ getOperateUndoReodoRecord(type: OperateTypeEnum, position: OperatePositionEnum, source: LinkedTreeNode, target?: LinkedTreeNode): UndoRedoRecord; /** 设置LinkedTree * @description 因为使用Ioc,无法在构造函数直接传入参,需要额外提供方法设置属性,在程序初始化的时候要设置相应的属性 */ setLinkedTree(linkedTree: LinkedTree): void; } @injectable() export abstract class TreeDataset implements ITreeDataset { private _linkedTree!: LinkedTree; setLinkedTree(linkedTree: LinkedTree) { this._linkedTree = linkedTree; } operate(type: OperateTypeEnum, position: OperatePositionEnum, source: LinkedTreeNode, target?: LinkedTreeNode) { switch (type) { case OperateTypeEnum.add: if (source && target) { position === OperatePositionEnum.children && this._linkedTree.addToChildrenLast(source, target); position === OperatePositionEnum.previous && this._linkedTree.addToBefore(source, target); position === OperatePositionEnum.next && this._linkedTree.addToAfter(source, target); } break; case OperateTypeEnum.move: if (source && target) { position === OperatePositionEnum.children && this._linkedTree.moveToChildrenLast(source, target); position === OperatePositionEnum.previous && this._linkedTree.moveToBefore(source, target); position === OperatePositionEnum.next && this._linkedTree.moveToAfter(source, target); } break; case OperateTypeEnum.delete: if (source) { position === OperatePositionEnum.self && this._linkedTree.remove(source); // 比较复杂,后续在实现 // position === OperatePositionEnum.children && source.RemoveSelf(); } break; } } getOperateUndoReodoRecord(type: OperateTypeEnum, position: OperatePositionEnum, source: LinkedTreeNode, target?: LinkedTreeNode): UndoRedoRecord { let data: UndoRedoRecord = { set: { params: [], action: '' }, restore: { params: [], action: '' } }; let action = type + '_' + position; let actionParis = TreeDndDatasetUndoRedoActionPairsCollection[action]; if (actionParis) { data.set.action = actionParis.set; data.restore.action = actionParis.restore; switch (type) { case OperateTypeEnum.add: if (source && target) { if (position === OperatePositionEnum.children || position === OperatePositionEnum.previous || position === OperatePositionEnum.next) { data.set.params.push(this._linkedTree, source, target); data.restore.params.push(this._linkedTree, source); } } break; case OperateTypeEnum.move: if (source && target) { let originalParent = source.parent!, originalNext = source.next!, addToChildren = !originalNext; if (position === OperatePositionEnum.children || position === OperatePositionEnum.previous || position === OperatePositionEnum.next ) { data.set.params.push(this._linkedTree, source, target); data.restore.params.push( this._linkedTree, source, addToChildren ? originalParent : originalNext, addToChildren ); } } break; case OperateTypeEnum.delete: if (source) { if (position === OperatePositionEnum.self) { let originalData = source.data!, originalParent = source.parent!, originalNext = source.next!, addToChildren = !originalNext; data.set.params.push(this._linkedTree, source); data.restore.params.push( this._linkedTree, new LinkedTreeNode(originalData), addToChildren ? originalParent : originalNext, addToChildren ); } // 比较复杂,后续在实现 //position === OperatePositionEnum.children && source.RemoveSelf(); } break; } } return data; } getUpdateDataRedoRecord(source: LinkedTreeNode, changes: Partial) { let changesCopy = deepClone(changes); let data: UndoRedoRecord = { set: { params: [], action: '' }, restore: { params: [], action: '' } }; let action = 'updateData'; let actionParis = TreeDndDatasetUndoRedoActionPairsCollection[action]; if (actionParis) { let partials = getPartialProperty(source.data, Object.keys(changesCopy)); data.set.action = actionParis.set; data.set.params.push(source.data, changesCopy); data.restore.action = actionParis.restore; data.restore.params.push(source.data, partials); } return data; } dispose() { //this._linkedTree.dispose(); } }