diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 012298a8e..b4ff17316 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -123,13 +123,16 @@ export class NodeChildren { if (node.isParental()) { foreachReverse(node.children, (subNode: Node) => { subNode.remove(useMutator, purge); - }); + }, (iterable, idx) => (iterable as NodeChildren).get(idx)); + foreachReverse(node.slots, (slotNode: Node) => { + slotNode.remove(useMutator, purge); + }, (iterable, idx) => (iterable as [])[idx]); } if (purge) { // should set parent null node.internalSetParent(null, useMutator); try { - node.purge(useMutator); + node.purge(); } catch (err) { console.error(err); } diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 892dd1359..82b471d9d 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -22,6 +22,8 @@ import { TransformStage } from './transform-stage'; import { ReactElement } from 'react'; import { SettingTopEntry } from 'designer/src/designer'; import { EventEmitter } from 'events'; +import { includeSlot, removeSlot } from '../../utils/slot'; +import { foreachReverse } from '../../utils/tree'; /** * 基础节点 @@ -317,6 +319,7 @@ export class Node { if (this.parent) { if (this.isSlot()) { this.parent.removeSlot(this, purge); + this.parent.children.delete(this, purge, useMutator); } else { this.parent.children.delete(this, purge, useMutator); } @@ -578,7 +581,11 @@ export class Node { import(data: Schema, checkId = false) { const { componentName, id, children, props, ...extras } = data; - + if (this.isSlot()) { + foreachReverse(this.children, (subNode: Node) => { + subNode.remove(true, true); + }, (iterable, idx) => (iterable as NodeChildren).get(idx)); + } if (this.isParental()) { this.props.import(props, extras); (this._children as NodeChildren).import(children, checkId); @@ -674,13 +681,13 @@ 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); + // 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; @@ -690,6 +697,11 @@ export class Node { } addSlot(slotNode: Node) { + const slotName = slotNode?.getExtraProp('name')?.getAsString(); + // 一个组件下的所有 slot,相同 slotName 的 slot 应该是唯一的 + if (includeSlot(this, slotName)) { + removeSlot(this, slotName); + } slotNode.internalSetParent(this as ParentalNode, true); this._slots.push(slotNode); } @@ -732,7 +744,7 @@ export class Node { this.purged = true; this.autoruns?.forEach((dispose) => dispose()); this.props.purge(); - this.document.destroyNode(this); + // this.document.destroyNode(this); } /** diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index 0671bffa9..18a90353b 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -271,7 +271,7 @@ export class Prop implements IPropParent { this.stash.clear(); } if (this._type !== 'slot' && this._slotNode) { - this._slotNode.purge(); + this._slotNode.remove(); this._slotNode = undefined; } } diff --git a/packages/designer/src/utils/slot.ts b/packages/designer/src/utils/slot.ts new file mode 100644 index 000000000..9061326b1 --- /dev/null +++ b/packages/designer/src/utils/slot.ts @@ -0,0 +1,20 @@ +import { Node } from '../document/node/node'; + +export function includeSlot(node: Node, slotName: string | undefined): boolean { + const { slots = [] } = node; + return slots.some(slot => { + return slotName && slotName === slot?.getExtraProp('name')?.getAsString(); + }); +} + +export function removeSlot(node: Node, slotName: string | undefined): boolean { + const { slots = [] } = node; + return slots.some((slot, idx) => { + if (slotName && slotName === slot?.getExtraProp('name')?.getAsString()) { + slot.remove(); + slots.splice(idx, 1); + return true; + } + return false; + }); +} diff --git a/packages/designer/src/utils/tree.ts b/packages/designer/src/utils/tree.ts index d850bb204..3f41f8c4c 100644 --- a/packages/designer/src/utils/tree.ts +++ b/packages/designer/src/utils/tree.ts @@ -1,7 +1,14 @@ import { NodeChildren } from '../document/node/node-children'; -export function foreachReverse(arr: NodeChildren, fn: Function, context: any = {}) { +type IterableArray = NodeChildren | any[]; + +export function foreachReverse( + arr: IterableArray, + action: (item: any) => void, + getter: (arr: IterableArray, index: number) => any, + context: any = {}, +) { for (let i = arr.length - 1; i >= 0; i--) { - fn.call(context, arr.get(i)); + action.call(context, getter(arr, i)); } -} +} \ No newline at end of file