fix: 优化树子节点删除逻辑

refactor: 增强对 react 组件的判断
This commit is contained in:
力皓 2020-09-08 17:49:38 +08:00
parent 7a6bf2cdb4
commit 47e814f807
5 changed files with 35 additions and 18 deletions

View File

@ -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, NodeType> = 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
}

View File

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

View File

@ -262,7 +262,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
}
// 解除老的父子关系,但不需要真的删除节点
if (this._parent) {
if (this._parent && !parent) {
if (this.isSlot()) {
this._parent.unlinkSlot(this);
} else {
@ -661,17 +661,17 @@ 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);
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;
}

View File

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

View File

@ -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<any> {
return obj && (isReactClass(obj) || typeof obj === 'function');
return obj && (isReactClass(obj) || typeof obj === 'function' || isForwardRefType(obj));
}
export function wrapReactClass(view: FunctionComponent) {