Merge branch 'fix/slot-duplication' into 'release/1.0.0'

Code review title: fix: 修复 slot 以及子节点不销毁
Code review Link: https://code.aone.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/codereview/4057087
This commit is contained in:
mark.ck 2020-11-11 11:22:17 +08:00
commit a4fa203f75
5 changed files with 57 additions and 15 deletions

View File

@ -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);
}

View File

@ -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<Schema extends NodeSchema = NodeSchema> {
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<Schema extends NodeSchema = NodeSchema> {
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<Schema extends NodeSchema = NodeSchema> {
* 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<Schema extends NodeSchema = NodeSchema> {
}
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<Schema extends NodeSchema = NodeSchema> {
this.purged = true;
this.autoruns?.forEach((dispose) => dispose());
this.props.purge();
this.document.destroyNode(this);
// this.document.destroyNode(this);
}
/**

View File

@ -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;
}
}

View File

@ -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;
});
}

View File

@ -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));
}
}
}