diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index 58d17a67f..47873449d 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -11,6 +11,7 @@ import { History } from './history'; import { TransformStage } from './node'; import { uniqueId } from '@ali/lowcode-utils'; import { ModalNodesManager } from './node'; +import { foreachReverse } from '../utils/tree'; export type GetDataType = T extends undefined ? NodeType extends { @@ -324,10 +325,13 @@ export class DocumentModel { } import(schema: RootSchema, checkId = false) { + // TODO: 暂时用饱和式删除,原因是 Slot 节点并不是树节点,无法正常递归删除 this.nodes.forEach(node => { this.internalRemoveAndPurgeNode(node, true); - this.destroyNode(node); }); + // foreachReverse(this.rootNode?.children, (node: Node) => { + // this.internalRemoveAndPurgeNode(node, true); + // }); this.rootNode?.import(schema as any, checkId); // todo: select added and active track added } diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 527b72c61..3f4bc4a27 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -4,6 +4,7 @@ import { TransformStage } from './transform-stage'; import { NodeData, isNodeSchema } from '@ali/lowcode-types'; import { shallowEqual } from '@ali/lowcode-utils'; import { EventEmitter } from 'events'; +import { foreachReverse } from '../../utils/tree'; export class NodeChildren { @obx.val private children: Node[]; @@ -118,7 +119,7 @@ export class NodeChildren { */ delete(node: Node, purge = false, useMutator = true): boolean { if (node.isParental()) { - node.children.forEach(subNode => { + foreachReverse(node.children, (subNode: Node) => { subNode.remove(useMutator, purge); }); } @@ -131,18 +132,19 @@ export class NodeChildren { console.error(err); } } + const document = node.document; + document.unlinkNode(node); + document.selection.remove(node.id); + document.destroyNode(node); + this.emitter.emit('change'); const i = this.children.indexOf(node); + if (useMutator) { + this.reportModified(node, this.owner, {type: 'remove', removeIndex: i, removeNode: node}); + } if (i < 0) { return false; } this.children.splice(i, 1); - const document = node.document; - document.unlinkNode(node); - document.selection.remove(node.id); - this.emitter.emit('change'); - if (useMutator) { - this.reportModified(node, this.owner, {type: 'remove', removeIndex: i, removeNode: node}); - } return false; } diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 5b11fc097..589cd8a15 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -262,7 +262,7 @@ export class Node { } // 解除老的父子关系,但不需要真的删除节点 - if (this._parent) { + if (this._parent && !parent) { if (this.isSlot()) { this._parent.unlinkSlot(this); } else { @@ -661,17 +661,17 @@ export class Node { * 删除一个Slot节点 */ removeSlot(slotNode: Node, purge = false): boolean { + if (purge) { + // should set parent null + slotNode?.internalSetParent(null, false); + slotNode?.purge(); + } + this.document.unlinkNode(slotNode); + this.document.selection.remove(slotNode.id); const i = this._slots.indexOf(slotNode); if (i < 0) { return false; } - if (purge) { - // should set parent null - slotNode.internalSetParent(null, false); - slotNode.purge(); - } - this.document.unlinkNode(slotNode); - this.document.selection.remove(slotNode.id); this._slots.splice(i, 1); return false; } diff --git a/packages/designer/src/utils/tree.ts b/packages/designer/src/utils/tree.ts new file mode 100644 index 000000000..2cd8ff515 --- /dev/null +++ b/packages/designer/src/utils/tree.ts @@ -0,0 +1,7 @@ +import { NodeChildren } from '../document/node/node-children'; + +export function foreachReverse(arr: NodeChildren, fn: Function, context: any = {}) { + for (let i = arr.length - 1; i >= 0; i--) { + fn.call(context, arr.get(i)); + } +} \ No newline at end of file diff --git a/packages/utils/src/is-react.ts b/packages/utils/src/is-react.ts index cb5059505..fdaed5f45 100644 --- a/packages/utils/src/is-react.ts +++ b/packages/utils/src/is-react.ts @@ -10,8 +10,12 @@ export function acceptsRef(obj: any): boolean { return obj?.prototype?.isReactComponent || (obj.$$typeof && obj.$$typeof === REACT_FORWARD_REF_TYPE); } +function isForwardRefType(obj: any): boolean { + return obj?.$$typeof && obj?.$$typeof === REACT_FORWARD_REF_TYPE; +} + export function isReactComponent(obj: any): obj is ComponentType { - return obj && (isReactClass(obj) || typeof obj === 'function'); + return obj && (isReactClass(obj) || typeof obj === 'function' || isForwardRefType(obj)); } export function wrapReactClass(view: FunctionComponent) {