mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-19 05:48:17 +00:00
fix: 优化树子节点删除逻辑
refactor: 增强对 react 组件的判断
This commit is contained in:
parent
7a6bf2cdb4
commit
47e814f807
@ -11,6 +11,7 @@ import { History } from './history';
|
|||||||
import { TransformStage } from './node';
|
import { TransformStage } from './node';
|
||||||
import { uniqueId } from '@ali/lowcode-utils';
|
import { uniqueId } from '@ali/lowcode-utils';
|
||||||
import { ModalNodesManager } from './node';
|
import { ModalNodesManager } from './node';
|
||||||
|
import { foreachReverse } from '../utils/tree';
|
||||||
|
|
||||||
export type GetDataType<T, NodeType> = T extends undefined
|
export type GetDataType<T, NodeType> = T extends undefined
|
||||||
? NodeType extends {
|
? NodeType extends {
|
||||||
@ -324,10 +325,13 @@ export class DocumentModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
import(schema: RootSchema, checkId = false) {
|
import(schema: RootSchema, checkId = false) {
|
||||||
|
// TODO: 暂时用饱和式删除,原因是 Slot 节点并不是树节点,无法正常递归删除
|
||||||
this.nodes.forEach(node => {
|
this.nodes.forEach(node => {
|
||||||
this.internalRemoveAndPurgeNode(node, true);
|
this.internalRemoveAndPurgeNode(node, true);
|
||||||
this.destroyNode(node);
|
|
||||||
});
|
});
|
||||||
|
// foreachReverse(this.rootNode?.children, (node: Node) => {
|
||||||
|
// this.internalRemoveAndPurgeNode(node, true);
|
||||||
|
// });
|
||||||
this.rootNode?.import(schema as any, checkId);
|
this.rootNode?.import(schema as any, checkId);
|
||||||
// todo: select added and active track added
|
// todo: select added and active track added
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { TransformStage } from './transform-stage';
|
|||||||
import { NodeData, isNodeSchema } from '@ali/lowcode-types';
|
import { NodeData, isNodeSchema } from '@ali/lowcode-types';
|
||||||
import { shallowEqual } from '@ali/lowcode-utils';
|
import { shallowEqual } from '@ali/lowcode-utils';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
|
import { foreachReverse } from '../../utils/tree';
|
||||||
|
|
||||||
export class NodeChildren {
|
export class NodeChildren {
|
||||||
@obx.val private children: Node[];
|
@obx.val private children: Node[];
|
||||||
@ -118,7 +119,7 @@ export class NodeChildren {
|
|||||||
*/
|
*/
|
||||||
delete(node: Node, purge = false, useMutator = true): boolean {
|
delete(node: Node, purge = false, useMutator = true): boolean {
|
||||||
if (node.isParental()) {
|
if (node.isParental()) {
|
||||||
node.children.forEach(subNode => {
|
foreachReverse(node.children, (subNode: Node) => {
|
||||||
subNode.remove(useMutator, purge);
|
subNode.remove(useMutator, purge);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -131,18 +132,19 @@ export class NodeChildren {
|
|||||||
console.error(err);
|
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);
|
const i = this.children.indexOf(node);
|
||||||
|
if (useMutator) {
|
||||||
|
this.reportModified(node, this.owner, {type: 'remove', removeIndex: i, removeNode: node});
|
||||||
|
}
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this.children.splice(i, 1);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -262,7 +262,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 解除老的父子关系,但不需要真的删除节点
|
// 解除老的父子关系,但不需要真的删除节点
|
||||||
if (this._parent) {
|
if (this._parent && !parent) {
|
||||||
if (this.isSlot()) {
|
if (this.isSlot()) {
|
||||||
this._parent.unlinkSlot(this);
|
this._parent.unlinkSlot(this);
|
||||||
} else {
|
} else {
|
||||||
@ -661,17 +661,17 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
|||||||
* 删除一个Slot节点
|
* 删除一个Slot节点
|
||||||
*/
|
*/
|
||||||
removeSlot(slotNode: Node, purge = false): boolean {
|
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);
|
const i = this._slots.indexOf(slotNode);
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
return false;
|
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);
|
this._slots.splice(i, 1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
7
packages/designer/src/utils/tree.ts
Normal file
7
packages/designer/src/utils/tree.ts
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,8 +10,12 @@ export function acceptsRef(obj: any): boolean {
|
|||||||
return obj?.prototype?.isReactComponent || (obj.$$typeof && obj.$$typeof === REACT_FORWARD_REF_TYPE);
|
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> {
|
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) {
|
export function wrapReactClass(view: FunctionComponent) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user