diff --git a/docs/docs/api/model/node-children.md b/docs/docs/api/model/node-children.md index 4c1b76b61..2e8769411 100644 --- a/docs/docs/api/model/node-children.md +++ b/docs/docs/api/model/node-children.md @@ -13,111 +13,298 @@ sidebar_position: 2 返回当前 children 实例所属的节点实例 +`@type {IPublicModelNode | null}` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + ### size children 内的节点实例数 -### isEmpty +`@type {number}` + + +### isEmptyNode 是否为空 +`@type {boolean}` + +**@since v1.1.0** +> v1.1.0 之前请使用 `isEmpty` + +### notEmptyNode + +是否不为空 + +`@type {boolean}` + +**@since v1.1.0** + ## 方法签名 ### delete - -delete(node: Node) - 删除指定节点 +```typescript +/** + * 删除指定节点 + * delete the node + * @param node + */ +delete(node: IPublicModelNode): boolean; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + ### insert -insert(node: Node, at?: number | null) - 插入一个节点 +```typescript +/** + * 删除指定节点 + * delete the node + * @param node + */ +delete(node: IPublicModelNode): boolean; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + + ### indexOf -indexOf(node: Node) - 返回指定节点的下标 +```typescript +/** + * 返回指定节点的下标 + * get index of node in current children + * @param node + * @returns + */ +indexOf(node: IPublicModelNode): number; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + ### splice -splice(start: number, deleteCount: number, node?: Node) - 类似数组 splice 操作 +```typescript +/** + * 类似数组 splice 操作 + * provide the same function with {Array.prototype.splice} + * @param start + * @param deleteCount + * @param node + */ +splice(start: number, deleteCount: number, node?: IPublicModelNode): any; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + + ### get -get(index: number) - 返回指定下标的节点 +```typescript +/** + * 返回指定下标的节点 + * get node with index + * @param index + * @returns + */ +get(index: number): IPublicModelNode | null; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + + ### has -has(node: Node) - 是否包含指定节点 +```typescript +/** + * 是否包含指定节点 + * check if node exists in current children + * @param node + * @returns + */ +has(node: IPublicModelNode): boolean; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + + ### forEach -forEach(fn: (node: Node, index: number) => void) - 类似数组的 forEach +```typescript +/** + * 类似数组的 forEach + * provide the same function with {Array.prototype.forEach} + * @param fn + */ +forEach(fn: (node: IPublicModelNode, index: number) => void): void; + +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + + ### map -map(fn: (node: Node, index: number) => T[]) - 类似数组的 map +```typescript +/** + * 类似数组的 map + * provide the same function with {Array.prototype.map} + * @param fn + */ +map(fn: (node: IPublicModelNode, index: number) => T[]): any[] | null; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + + ### every -every(fn: (node: Node, index: number) => boolean) - 类似数组的 every +```typescript +/** + * 类似数组的 every + * provide the same function with {Array.prototype.every} + * @param fn + */ +every(fn: (node: IPublicModelNode, index: number) => boolean): boolean; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + + ### some -some(fn: (node: Node, index: number) => boolean) - 类似数组的 some +```typescript +/** + * 类似数组的 some + * provide the same function with {Array.prototype.some} + * @param fn + */ +some(fn: (node: IPublicModelNode, index: number) => boolean): boolean; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + + ### filter -filter(fn: (node: Node, index: number) => boolean) - 类似数组的 filter +```typescript +/** + * 类似数组的 filter + * provide the same function with {Array.prototype.filter} + * @param fn + */ +filter(fn: (node: IPublicModelNode, index: number) => boolean): any; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + + ### find -find(fn: (node: Node, index: number) => boolean) - 类似数组的 find +```typescript +/** + * 类似数组的 find + * provide the same function with {Array.prototype.find} + * @param fn + */ +find(fn: (node: IPublicModelNode, index: number) => boolean): IPublicModelNode | null; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + + ### reduce -reduce(fn: (acc: any, cur: Node) => any, initialValue: any) - 类似数组的 reduce +```typescript +/** + * 类似数组的 reduce + * provide the same function with {Array.prototype.reduce} + * @param fn + */ +reduce(fn: (acc: any, cur: IPublicModelNode) => any, initialValue: any): void; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + + ### importSchema -importSchema(data?: NodeData | NodeData[]) - 导入 schema +```typescript +/** + * 导入 schema + * import schema + * @param data + */ +importSchema(data?: IPublicTypeNodeData | IPublicTypeNodeData[]): void; +``` + +相关类型:[IPublicTypeNodeData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-data.ts) + + ### exportSchema - -exportSchema(stage: IPulicEnumTransformStage = IPulicEnumTransformStage.Render) - 导出 schema +```typescript +/** + * 导出 schema + * export schema + * @param stage + */ +exportSchema(stage: IPublicEnumTransformStage): IPublicTypeNodeSchema; +``` + +相关类型: +- [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts) +- [IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts) + + ### mergeChildren -mergeChildren( - remover: (node: Node, idx: number) => boolean, - adder: (children: Node[]) => any, - sorter: (firstNode: Node, secondNode: Node) => number, - ) +执行新增、删除、排序等操作 -执行新增、删除、排序等操作 \ No newline at end of file +```typescript +/** + * 执行新增、删除、排序等操作 + * excute remove/add/sort operations + * @param remover + * @param adder + * @param sorter + */ +mergeChildren( + remover: (node: IPublicModelNode, idx: number) => boolean, + adder: (children: IPublicModelNode[]) => IPublicTypeNodeData[] | null, + sorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number +): any; +``` + +相关类型: +- [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) +- [IPublicTypeNodeData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-data.ts) diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 3604ce4be..9993f4c04 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -10,18 +10,68 @@ export interface IOnChangeOptions { node: Node; } -export interface INodeChildren extends IPublicModelNodeChildren { +export interface INodeChildren extends Omit { + unlinkChild(node: INode): void; + /** + * 删除一个节点 + */ + internalDelete( + node: INode, + purge: boolean, + useMutator: boolean, + options: NodeRemoveOptions + ): boolean; + /** + * 插入一个节点,返回新长度 + */ + internalInsert(node: INode, at?: number | null, useMutator?: boolean): void; + + import(data?: IPublicTypeNodeData | IPublicTypeNodeData[], checkId?: boolean): void; + + /** + * 导出 schema + */ + export(stage: IPublicEnumTransformStage): IPublicTypeNodeData[]; + + /** following methods are overriding super interface, using different param types */ + /** overriding methods start */ + + forEach(fn: (item: INode, index: number) => void): void; + + map(fn: (item: INode, index: number) => T): T[] | null; + + every(fn: (item: INode, index: number) => any): boolean; + + some(fn: (item: INode, index: number) => any): boolean; + + filter(fn: (item: INode, index: number) => any): any; + + find(fn: (item: INode, index: number) => boolean): any; + + reduce(fn: (acc: any, cur: INode) => any, initialValue: any): void; + + mergeChildren( + remover: (node: INode, idx: number) => boolean, + adder: (children: INode[]) => IPublicTypeNodeData[] | null, + sorter: (firstNode: INode, secondNode: INode) => number, + ): any; + + /** overriding methods end */ } export class NodeChildren implements INodeChildren { @obx.shallow private children: INode[]; private emitter: IEventBus = createModuleEventBus('NodeChildren'); - constructor(readonly owner: INode, data: IPublicTypeNodeData | IPublicTypeNodeData[], options: any = {}) { + constructor( + readonly owner: INode, + data: IPublicTypeNodeData | IPublicTypeNodeData[], + options: any = {}, + ) { makeObservable(this); this.children = (Array.isArray(data) ? data : [data]).map((child) => { - return this.owner.document.createNode(child, options.checkId); + return this.owner.document?.createNode(child, options.checkId); }); } @@ -36,7 +86,7 @@ export class NodeChildren implements INodeChildren { stage = compatStage(stage); return this.children.map((node) => { const data = node.export(stage); - if (node.isLeaf() && IPublicEnumTransformStage.Save === stage) { + if (node.isLeafNode && IPublicEnumTransformStage.Save === stage) { // FIXME: filter empty return data.children as IPublicTypeNodeData; } @@ -88,13 +138,21 @@ export class NodeChildren implements INodeChildren { } /** - * 是否空 + * */ isEmpty() { + return this.isEmptyNode; + } + + get isEmptyNode(): boolean { return this.size < 1; } notEmpty() { + return this.notEmptyNode; + } + + get notEmptyNode(): boolean { return this.size > 0; } @@ -132,9 +190,16 @@ export class NodeChildren implements INodeChildren { /** * 删除一个节点 */ - delete(node: INode, purge = false, useMutator = true, options: NodeRemoveOptions = {}): boolean { + delete(node: INode): boolean { + return this.internalDelete(node); + } + + /** + * 删除一个节点 + */ + internalDelete(node: INode, purge = false, useMutator = true, options: NodeRemoveOptions = {}): boolean { node.internalPurgeStart(); - if (node.isParental()) { + if (node.isParentalNode) { foreachReverse( node.children, (subNode: Node) => { @@ -168,9 +233,9 @@ export class NodeChildren implements INodeChildren { const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor'); editor.eventBus.emit('node.remove', { node, index: i }); } - document.unlinkNode(node); - document.selection.remove(node.id); - document.destroyNode(node); + document?.unlinkNode(node); + document?.selection.remove(node.id); + document?.destroyNode(node); this.emitter.emit('change', { type: 'delete', node, @@ -191,10 +256,14 @@ export class NodeChildren implements INodeChildren { return false; } + insert(node: INode, at?: number | null): void { + this.internalInsert(node, at, true); + } + /** * 插入一个节点,返回新长度 */ - insert(node: INode, at?: number | null, useMutator = true): void { + internalInsert(node: INode, at?: number | null, useMutator = true): void { const { children } = this; let index = at == null || at === -1 ? children.length : at; @@ -349,7 +418,7 @@ export class NodeChildren implements INodeChildren { return this.children.some((child, index) => fn(child, index)); } - filter(fn: (item: INode, index: number) => any) { + filter(fn: (item: INode, index: number) => any): any { return this.children.filter(fn); } @@ -384,7 +453,7 @@ export class NodeChildren implements INodeChildren { const items = adder(this.children); if (items && items.length > 0) { items.forEach((child: IPublicTypeNodeData) => { - const node = this.owner.document.createNode(child); + const node = this.owner.document?.createNode(child); this.children.push(node); node.internalSetParent(this.owner); }); @@ -423,10 +492,10 @@ export class NodeChildren implements INodeChildren { if (!node) { return; } - if (node.isRoot()) { + if (node.isRootNode) { return; } - const callbacks = owner.componentMeta.getMetadata().configure.advanced?.callbacks; + const callbacks = owner.componentMeta?.getMetadata().configure.advanced?.callbacks; if (callbacks?.onSubtreeModified) { try { callbacks?.onSubtreeModified.call( @@ -439,7 +508,7 @@ export class NodeChildren implements INodeChildren { } } - if (owner.parent && !owner.parent.isRoot()) { + if (owner.parent && !owner.parent.isRootNode) { this.reportModified(node, owner.parent, { ...options, propagated: true }); } } diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 169dc5cbf..67eb817bf 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -22,7 +22,7 @@ import { compatStage, isDOMText, isJSExpression } from '@alilc/lowcode-utils'; import { SettingTopEntry } from '@alilc/lowcode-designer'; import { Props, getConvertedExtraKey } from './props/props'; import { DocumentModel } from '../document-model'; -import { NodeChildren } from './node-children'; +import { NodeChildren, INodeChildren } from './node-children'; import { Prop } from './props/prop'; import { ComponentMeta } from '../../component-meta'; import { ExclusiveGroup, isExclusiveGroup } from './exclusive-group'; @@ -36,6 +36,22 @@ export interface INode extends IPublicModelNode { setVisible(flag: boolean): void; getVisible(): boolean; + + /** + * 内部方法,请勿使用 + * @param useMutator 是否触发联动逻辑 + */ + internalSetParent(parent: INode | null, useMutator: boolean): void; + + setConditionGroup(grp: IPublicModelExclusiveGroup | string | null): void; + + internalToShellNode(): IPublicModelNode | null; + + internalPurgeStart(): void; + + unlinkSlot(slotNode: Node): void; + + didDropOut(dragment: Node): void; } /** @@ -116,7 +132,7 @@ export class Node */ props: Props; - protected _children?: NodeChildren; + protected _children?: INodeChildren; /** * @deprecated @@ -135,7 +151,7 @@ export class Node /** * 当前节点子集 */ - get children(): NodeChildren | null { + get children(): INodeChildren | null { return this._children || null; } @@ -390,7 +406,7 @@ export class Node if (this.isSlot()) { this._parent.unlinkSlot(this); } else { - this._parent.children.unlinkChild(this); + this._parent.children?.unlinkChild(this); } } if (useMutator) { @@ -449,9 +465,9 @@ export class Node } if (this.isSlot()) { this.parent.removeSlot(this, purge); - this.parent.children.delete(this, purge, useMutator, { suppressRemoveEvent: true }); + this.parent.children.internalDelete(this, purge, useMutator, { suppressRemoveEvent: true }); } else { - this.parent.children.delete(this, purge, useMutator, { suppressRemoveEvent: true }); + this.parent.children.internalDelete(this, purge, useMutator, { suppressRemoveEvent: true }); } } } @@ -965,12 +981,12 @@ export class Node insertBefore(node: Node, ref?: Node, useMutator = true) { const nodeInstance = ensureNode(node, this.document); - this.children?.insert(nodeInstance, ref ? ref.index : null, useMutator); + this.children?.internalInsert(nodeInstance, ref ? ref.index : null, useMutator); } insertAfter(node: any, ref?: Node, useMutator = true) { const nodeInstance = ensureNode(node, this.document); - this.children?.insert(nodeInstance, ref ? ref.index + 1 : null, useMutator); + this.children?.internalInsert(nodeInstance, ref ? ref.index + 1 : null, useMutator); } getParent() { @@ -1337,7 +1353,7 @@ export function insertChild( node = container.document.createNode(thing); } - container.children.insert(node, at); + container.children.internalInsert(node, at); return node; } diff --git a/packages/designer/tests/designer/designer.test.ts b/packages/designer/tests/designer/designer.test.ts index 4a00017e8..8bca7d84a 100644 --- a/packages/designer/tests/designer/designer.test.ts +++ b/packages/designer/tests/designer/designer.test.ts @@ -103,6 +103,7 @@ describe('Designer 测试', () => { return x; }, insert() {}, + internalInsert() {}, }, }; const mockDetail = { type: 'Children', index: 1, near: { node: { x: 1 } } }; @@ -172,6 +173,7 @@ describe('Designer 测试', () => { return x; }, insert() {}, + internalInsert() {}, }, }; const mockDetail = { type: 'Children', index: 1, near: { node: { x: 1 } } }; @@ -407,6 +409,7 @@ describe('Designer 测试', () => { return x; }, insert() {}, + internalInsert() {}, }, }; const mockDetail = { type: 'Children', index: 1, near: { node: { x: 1 } } }; @@ -431,6 +434,7 @@ describe('Designer 测试', () => { return x; }, insert() {}, + internalInsert() {}, }, }, detail: mockDetail, diff --git a/packages/shell/src/model/node-children.ts b/packages/shell/src/model/node-children.ts index 702cfa82f..9f8792ee3 100644 --- a/packages/shell/src/model/node-children.ts +++ b/packages/shell/src/model/node-children.ts @@ -1,16 +1,16 @@ -import { Node as InnerNode } from '@alilc/lowcode-designer'; -import { IPublicTypeNodeSchema, IPublicTypeNodeData, IPublicEnumTransformStage, IPublicModelNodeChildren, IPublicModelNode } from '@alilc/lowcode-types'; +import { INode as InnerNode, INodeChildren } from '@alilc/lowcode-designer'; +import { IPublicTypeNodeData, IPublicEnumTransformStage, IPublicModelNodeChildren, IPublicModelNode } from '@alilc/lowcode-types'; import { Node } from './node'; import { nodeSymbol, nodeChildrenSymbol } from '../symbols'; export class NodeChildren implements IPublicModelNodeChildren { - private readonly [nodeChildrenSymbol]: IPublicModelNodeChildren; + private readonly [nodeChildrenSymbol]: INodeChildren; - constructor(nodeChildren: IPublicModelNodeChildren) { + constructor(nodeChildren: INodeChildren) { this[nodeChildrenSymbol] = nodeChildren; } - static create(nodeChildren: IPublicModelNodeChildren | null): IPublicModelNodeChildren | null { + static create(nodeChildren: INodeChildren | null): IPublicModelNodeChildren | null { if (!nodeChildren) { return null; } @@ -37,7 +37,7 @@ export class NodeChildren implements IPublicModelNodeChildren { * @returns */ get isEmpty(): boolean { - return this[nodeChildrenSymbol].isEmpty(); + return this[nodeChildrenSymbol].isEmptyNode; } /** @@ -45,7 +45,7 @@ export class NodeChildren implements IPublicModelNodeChildren { * @returns */ get isEmptyNode(): boolean { - return this[nodeChildrenSymbol].isEmpty(); + return this[nodeChildrenSymbol].isEmptyNode; } /** @@ -53,23 +53,23 @@ export class NodeChildren implements IPublicModelNodeChildren { * judge if it is not empty */ get notEmpty(): boolean { - return this[nodeChildrenSymbol].notEmpty(); + return this[nodeChildrenSymbol].notEmptyNode; } /** * judge if it is not empty */ get notEmptyNode(): boolean { - return this[nodeChildrenSymbol].notEmpty(); + return this[nodeChildrenSymbol].notEmptyNode; } /** * 删除指定节点 + * delete the node * @param node - * @returns */ delete(node: IPublicModelNode): boolean { - return this[nodeChildrenSymbol].delete((node as any)); + return this[nodeChildrenSymbol].delete((node as any)?.[nodeSymbol]); } /** @@ -79,7 +79,7 @@ export class NodeChildren implements IPublicModelNodeChildren { * @returns */ insert(node: IPublicModelNode, at?: number | null): void { - return this[nodeChildrenSymbol].insert((node as any), at, true); + return this[nodeChildrenSymbol].insert((node as any)?.[nodeSymbol], at); } /** @@ -88,7 +88,7 @@ export class NodeChildren implements IPublicModelNodeChildren { * @returns */ indexOf(node: IPublicModelNode): number { - return this[nodeChildrenSymbol].indexOf((node as any)); + return this[nodeChildrenSymbol].indexOf((node as any)?.[nodeSymbol]); } /** @@ -106,7 +106,7 @@ export class NodeChildren implements IPublicModelNodeChildren { * @param index * @returns */ - get(index: number): any { + get(index: number): IPublicModelNode | null { return Node.create(this[nodeChildrenSymbol].get(index)); } @@ -116,7 +116,7 @@ export class NodeChildren implements IPublicModelNodeChildren { * @returns */ has(node: IPublicModelNode): boolean { - return this[nodeChildrenSymbol].has((node as any)); + return this[nodeChildrenSymbol].has((node as any)?.[nodeSymbol]); } /** @@ -124,7 +124,7 @@ export class NodeChildren implements IPublicModelNodeChildren { * @param fn */ forEach(fn: (node: IPublicModelNode, index: number) => void): void { - this[nodeChildrenSymbol].forEach((item: InnerNode, index: number) => { + this[nodeChildrenSymbol].forEach((item: InnerNode, index: number) => { fn(Node.create(item)!, index); }); } @@ -134,7 +134,7 @@ export class NodeChildren implements IPublicModelNodeChildren { * @param fn */ map(fn: (node: IPublicModelNode, index: number) => T[]): any[] | null { - return this[nodeChildrenSymbol].map((item: InnerNode, index: number) => { + return this[nodeChildrenSymbol].map((item: InnerNode, index: number) => { return fn(Node.create(item)!, index); }); } @@ -144,7 +144,7 @@ export class NodeChildren implements IPublicModelNodeChildren { * @param fn */ every(fn: (node: IPublicModelNode, index: number) => boolean): boolean { - return this[nodeChildrenSymbol].every((item: InnerNode, index: number) => { + return this[nodeChildrenSymbol].every((item: InnerNode, index: number) => { return fn(Node.create(item)!, index); }); } @@ -154,7 +154,7 @@ export class NodeChildren implements IPublicModelNodeChildren { * @param fn */ some(fn: (node: IPublicModelNode, index: number) => boolean): boolean { - return this[nodeChildrenSymbol].some((item: InnerNode, index: number) => { + return this[nodeChildrenSymbol].some((item: InnerNode, index: number) => { return fn(Node.create(item)!, index); }); } @@ -165,10 +165,10 @@ export class NodeChildren implements IPublicModelNodeChildren { */ filter(fn: (node: IPublicModelNode, index: number) => boolean): any { return this[nodeChildrenSymbol] - .filter((item: InnerNode, index: number) => { + .filter((item: InnerNode, index: number) => { return fn(Node.create(item)!, index); }) - .map((item: InnerNode) => Node.create(item)!); + .map((item: InnerNode) => Node.create(item)!); } /** @@ -177,7 +177,7 @@ export class NodeChildren implements IPublicModelNodeChildren { */ find(fn: (node: IPublicModelNode, index: number) => boolean): IPublicModelNode | null { return Node.create( - this[nodeChildrenSymbol].find((item: InnerNode, index: number) => { + this[nodeChildrenSymbol].find((item: InnerNode, index: number) => { return fn(Node.create(item)!, index); }), ); @@ -219,8 +219,9 @@ export class NodeChildren implements IPublicModelNodeChildren { mergeChildren( remover: (node: IPublicModelNode, idx: number) => boolean, adder: (children: IPublicModelNode[]) => any, - sorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number, + originalSorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number, ) { + let sorter = originalSorter; if (!sorter) { sorter = () => 0; } diff --git a/packages/types/src/shell/model/node-children.ts b/packages/types/src/shell/model/node-children.ts index e0df7d24c..c6fde9403 100644 --- a/packages/types/src/shell/model/node-children.ts +++ b/packages/types/src/shell/model/node-children.ts @@ -5,11 +5,13 @@ import { IPublicModelNode } from './'; export interface IPublicModelNodeChildren { /** * 返回当前 children 实例所属的节点实例 + * get owner node of this nodeChildren */ get owner(): IPublicModelNode | null; /** * children 内的节点实例数 + * get count of child nodes */ get size(): number; @@ -39,13 +41,14 @@ export interface IPublicModelNodeChildren { /** * 删除指定节点 + * delete the node * @param node - * @returns */ delete(node: IPublicModelNode): boolean; /** * 插入一个节点 + * insert a node at specific position * @param node 待插入节点 * @param at 插入下标 * @returns @@ -54,6 +57,7 @@ export interface IPublicModelNodeChildren { /** * 返回指定节点的下标 + * get index of node in current children * @param node * @returns */ @@ -61,6 +65,7 @@ export interface IPublicModelNodeChildren { /** * 类似数组 splice 操作 + * provide the same function with {Array.prototype.splice} * @param start * @param deleteCount * @param node @@ -69,13 +74,15 @@ export interface IPublicModelNodeChildren { /** * 返回指定下标的节点 + * get node with index * @param index * @returns */ - get(index: number): any; + get(index: number): IPublicModelNode | null; /** * 是否包含指定节点 + * check if node exists in current children * @param node * @returns */ @@ -83,55 +90,74 @@ export interface IPublicModelNodeChildren { /** * 类似数组的 forEach + * provide the same function with {Array.prototype.forEach} * @param fn */ forEach(fn: (node: IPublicModelNode, index: number) => void): void; /** * 类似数组的 map + * provide the same function with {Array.prototype.map} * @param fn */ map(fn: (node: IPublicModelNode, index: number) => T[]): any[] | null; /** * 类似数组的 every + * provide the same function with {Array.prototype.every} * @param fn */ every(fn: (node: IPublicModelNode, index: number) => boolean): boolean; /** * 类似数组的 some + * provide the same function with {Array.prototype.some} * @param fn */ some(fn: (node: IPublicModelNode, index: number) => boolean): boolean; /** * 类似数组的 filter + * provide the same function with {Array.prototype.filter} * @param fn */ filter(fn: (node: IPublicModelNode, index: number) => boolean): any; /** * 类似数组的 find + * provide the same function with {Array.prototype.find} * @param fn */ find(fn: (node: IPublicModelNode, index: number) => boolean): IPublicModelNode | null; + /** + * 类似数组的 reduce + * provide the same function with {Array.prototype.reduce} + * @param fn + */ reduce(fn: (acc: any, cur: IPublicModelNode) => any, initialValue: any): void; /** * 导入 schema + * import schema * @param data */ importSchema(data?: IPublicTypeNodeData | IPublicTypeNodeData[]): void; /** * 导出 schema + * export schema * @param stage - * @returns */ exportSchema(stage: IPublicEnumTransformStage): IPublicTypeNodeSchema; + /** + * 执行新增、删除、排序等操作 + * excute remove/add/sort operations + * @param remover + * @param adder + * @param sorter + */ mergeChildren( remover: (node: IPublicModelNode, idx: number) => boolean, adder: (children: IPublicModelNode[]) => IPublicTypeNodeData[] | null,