|
@@ -6,25 +6,26 @@ export interface TreeRaw {
|
|
|
seq: number;
|
|
seq: number;
|
|
|
[props: string]: any;
|
|
[props: string]: any;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-export interface TreeNode extends TreeRaw {
|
|
|
|
|
- getCtx: () => NodeContext; // ctx对象改为getCtx(),因为handsontable数据循环引用会报错
|
|
|
|
|
|
|
+interface Node<T extends TreeRaw = TreeRaw> extends TreeRaw {
|
|
|
|
|
+ getCtx: () => NodeContext<T>; // ctx对象改为getCtx(),因为handsontable数据循环引用会报错
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-export interface TreeIDMap<T = any> {
|
|
|
|
|
- [propName: string]: TreeNode & T;
|
|
|
|
|
|
|
+export type TreeNode<T extends TreeRaw = TreeRaw> = Node<T> & T;
|
|
|
|
|
+
|
|
|
|
|
+export interface TreeIDMap<T extends TreeRaw = TreeRaw> {
|
|
|
|
|
+ [propName: string]: TreeNode<T>;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-export interface CtxIDMap<T = any> {
|
|
|
|
|
|
|
+export interface CtxIDMap<T extends TreeRaw = TreeRaw> {
|
|
|
[propName: string]: NodeContext<T>;
|
|
[propName: string]: NodeContext<T>;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-export interface TreeParentMap<T = any> {
|
|
|
|
|
- [propName: string]: (TreeNode & T)[];
|
|
|
|
|
|
|
+export interface TreeParentMap<T extends TreeRaw = TreeRaw> {
|
|
|
|
|
+ [propName: string]: TreeNode<T>[];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-export interface ParentMap<T = any> {
|
|
|
|
|
- [propName: string]: ((TreeRaw | TreeNode) & T)[];
|
|
|
|
|
|
|
+export interface ParentMap<T extends TreeRaw = TreeRaw> {
|
|
|
|
|
+ [propName: string]: (TreeRaw | TreeNode<T>)[];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export interface UpdateItem {
|
|
export interface UpdateItem {
|
|
@@ -40,12 +41,12 @@ export interface UpdateData {
|
|
|
|
|
|
|
|
export type None = null | undefined;
|
|
export type None = null | undefined;
|
|
|
|
|
|
|
|
-export class Tree<T = any> {
|
|
|
|
|
|
|
+export class Tree<T extends TreeRaw = TreeRaw> {
|
|
|
// 原始数据,不经过排序的数据
|
|
// 原始数据,不经过排序的数据
|
|
|
- rawData: (TreeNode & T)[];
|
|
|
|
|
|
|
+ rawData: TreeNode<T>[];
|
|
|
|
|
|
|
|
// 按照树结构拼装好、排好序的数据。实际只是原始数据进行排序,内部元素跟原始数据内部元素的引用是一致的
|
|
// 按照树结构拼装好、排好序的数据。实际只是原始数据进行排序,内部元素跟原始数据内部元素的引用是一致的
|
|
|
- data: (TreeNode & T)[];
|
|
|
|
|
|
|
+ data: TreeNode<T>[];
|
|
|
|
|
|
|
|
rootID: string;
|
|
rootID: string;
|
|
|
|
|
|
|
@@ -64,7 +65,7 @@ export class Tree<T = any> {
|
|
|
constructor(rawData: TreeRaw[], rootID = '-1') {
|
|
constructor(rawData: TreeRaw[], rootID = '-1') {
|
|
|
this.rootID = rootID;
|
|
this.rootID = rootID;
|
|
|
this.rawData = this.genNodeContext(rawData);
|
|
this.rawData = this.genNodeContext(rawData);
|
|
|
- this.rawData = Tree.sort(this.rawData);
|
|
|
|
|
|
|
+ this.rawData = this.sort(this.rawData);
|
|
|
this.data = [];
|
|
this.data = [];
|
|
|
this.IDMap = {};
|
|
this.IDMap = {};
|
|
|
this.parentMap = {};
|
|
this.parentMap = {};
|
|
@@ -74,27 +75,27 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 根据seq进行排序
|
|
// 根据seq进行排序
|
|
|
- static sort<U extends TreeNode | TreeRaw>(nodes: U[]): U[] {
|
|
|
|
|
|
|
+ sort(nodes: TreeNode<T>[]): TreeNode<T>[] {
|
|
|
return nodes.sort((a, b) => a.seq - b.seq);
|
|
return nodes.sort((a, b) => a.seq - b.seq);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 获取节点的所有parentID
|
|
// 获取节点的所有parentID
|
|
|
- static getParentIDList(nodes: TreeNode[]): Set<string> {
|
|
|
|
|
|
|
+ getParentIDList(nodes: TreeNode<T>[]): Set<string> {
|
|
|
const parentIDList: Set<string> = new Set();
|
|
const parentIDList: Set<string> = new Set();
|
|
|
nodes.forEach(node => parentIDList.add(node.parentID));
|
|
nodes.forEach(node => parentIDList.add(node.parentID));
|
|
|
return parentIDList;
|
|
return parentIDList;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 生成节点getCtx方法(由于handsontable循环引用bug,将ctx对象改为getCtx方法),用于获取节点上下文,挂载相关节点方法,TreeRaw转换为TreeNode
|
|
// 生成节点getCtx方法(由于handsontable循环引用bug,将ctx对象改为getCtx方法),用于获取节点上下文,挂载相关节点方法,TreeRaw转换为TreeNode
|
|
|
- private genNodeContext(rawData: TreeRaw[]): (TreeNode & T)[] {
|
|
|
|
|
|
|
+ private genNodeContext(rawData: TreeRaw[]): TreeNode<T>[] {
|
|
|
rawData.forEach(item => {
|
|
rawData.forEach(item => {
|
|
|
item.getCtx = () => this.ctxMap[item.ID];
|
|
item.getCtx = () => this.ctxMap[item.ID];
|
|
|
});
|
|
});
|
|
|
- return rawData as (TreeNode & T)[];
|
|
|
|
|
|
|
+ return rawData as TreeNode<T>[];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 生成映射表
|
|
// 生成映射表
|
|
|
- private genMap(data: (TreeNode & T)[]): void {
|
|
|
|
|
|
|
+ private genMap(data: TreeNode<T>[]): void {
|
|
|
data.forEach(item => {
|
|
data.forEach(item => {
|
|
|
this.IDMap[item.ID] = item;
|
|
this.IDMap[item.ID] = item;
|
|
|
this.ctxMap[item.ID] = new NodeContext(item, this);
|
|
this.ctxMap[item.ID] = new NodeContext(item, this);
|
|
@@ -105,7 +106,7 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 获取顶层原始数据
|
|
// 获取顶层原始数据
|
|
|
- getRoots(): (TreeNode & T)[] {
|
|
|
|
|
|
|
+ getRoots(): TreeNode<T>[] {
|
|
|
return this.parentMap[this.rootID] || [];
|
|
return this.parentMap[this.rootID] || [];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -113,7 +114,7 @@ export class Tree<T = any> {
|
|
|
private genData(): void {
|
|
private genData(): void {
|
|
|
// genData时不需要排序,因为rawData已经排好序
|
|
// genData时不需要排序,因为rawData已经排好序
|
|
|
const roots = this.getRoots();
|
|
const roots = this.getRoots();
|
|
|
- const pushNodesToData = (nodes: (TreeNode & T)[]): void => {
|
|
|
|
|
|
|
+ const pushNodesToData = (nodes: TreeNode<T>[]): void => {
|
|
|
nodes.forEach(node => {
|
|
nodes.forEach(node => {
|
|
|
this.data.push(node);
|
|
this.data.push(node);
|
|
|
const children = this.parentMap[node.ID];
|
|
const children = this.parentMap[node.ID];
|
|
@@ -132,11 +133,11 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 将相关parentMap内的数据、data进行重新排序。新增、删除等操作进行完后,数据需要重新排序
|
|
// 将相关parentMap内的数据、data进行重新排序。新增、删除等操作进行完后,数据需要重新排序
|
|
|
- reSortData(nodes: (TreeNode & T)[]): void {
|
|
|
|
|
- const toSortList = Tree.getParentIDList(nodes);
|
|
|
|
|
|
|
+ reSortData(nodes: TreeNode<T>[]): void {
|
|
|
|
|
+ const toSortList = this.getParentIDList(nodes);
|
|
|
toSortList.forEach(parentID => {
|
|
toSortList.forEach(parentID => {
|
|
|
if (this.parentMap[parentID] && this.parentMap[parentID].length) {
|
|
if (this.parentMap[parentID] && this.parentMap[parentID].length) {
|
|
|
- Tree.sort(this.parentMap[parentID]);
|
|
|
|
|
|
|
+ this.sort(this.parentMap[parentID]);
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
this.reGenData();
|
|
this.reGenData();
|
|
@@ -146,19 +147,19 @@ export class Tree<T = any> {
|
|
|
resortDataByID(parentIDList: string[]): void {
|
|
resortDataByID(parentIDList: string[]): void {
|
|
|
parentIDList.forEach(parentID => {
|
|
parentIDList.forEach(parentID => {
|
|
|
if (this.parentMap[parentID] && this.parentMap[parentID].length) {
|
|
if (this.parentMap[parentID] && this.parentMap[parentID].length) {
|
|
|
- Tree.sort(this.parentMap[parentID]);
|
|
|
|
|
|
|
+ this.sort(this.parentMap[parentID]);
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
this.reGenData();
|
|
this.reGenData();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 查找ID节点
|
|
// 查找ID节点
|
|
|
- find(ID: string): (TreeNode & T) | null {
|
|
|
|
|
|
|
+ find(ID: string): TreeNode<T> | null {
|
|
|
return this.IDMap[ID] || null;
|
|
return this.IDMap[ID] || null;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 查找ID节点的父节点
|
|
// 查找ID节点的父节点
|
|
|
- findParent(ID: string): (TreeNode & T) | null {
|
|
|
|
|
|
|
+ findParent(ID: string): TreeNode<T> | null {
|
|
|
const node = this.find(ID);
|
|
const node = this.find(ID);
|
|
|
if (!node) {
|
|
if (!node) {
|
|
|
return null;
|
|
return null;
|
|
@@ -167,7 +168,7 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 查找ID节点的下一个节点
|
|
// 查找ID节点的下一个节点
|
|
|
- findNext(ID: string): (TreeNode & T) | null {
|
|
|
|
|
|
|
+ findNext(ID: string): TreeNode<T> | null {
|
|
|
const node = this.find(ID);
|
|
const node = this.find(ID);
|
|
|
if (!node) {
|
|
if (!node) {
|
|
|
return null;
|
|
return null;
|
|
@@ -181,7 +182,7 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 查找ID节点的上一个节点
|
|
// 查找ID节点的上一个节点
|
|
|
- findPrev(ID: string): (TreeNode & T) | null {
|
|
|
|
|
|
|
+ findPrev(ID: string): TreeNode<T> | null {
|
|
|
const node = this.find(ID);
|
|
const node = this.find(ID);
|
|
|
if (!node) {
|
|
if (!node) {
|
|
|
return null;
|
|
return null;
|
|
@@ -195,7 +196,7 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 查询ID节点的子节点
|
|
// 查询ID节点的子节点
|
|
|
- findChildren(ID: string): (TreeNode & T)[] {
|
|
|
|
|
|
|
+ findChildren(ID: string): TreeNode<T>[] {
|
|
|
return this.parentMap[ID] || [];
|
|
return this.parentMap[ID] || [];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -212,11 +213,11 @@ export class Tree<T = any> {
|
|
|
|
|
|
|
|
// 递归获取节点
|
|
// 递归获取节点
|
|
|
getNodesPosterity(
|
|
getNodesPosterity(
|
|
|
- treeNodes: (TreeNode & T)[],
|
|
|
|
|
|
|
+ treeNodes: TreeNode<T>[],
|
|
|
includeSelf = true
|
|
includeSelf = true
|
|
|
- ): (TreeNode & T)[] {
|
|
|
|
|
- const rst: (TreeNode & T)[] = [];
|
|
|
|
|
- const pushNodes = (nodes: (TreeNode & T)[]): void => {
|
|
|
|
|
|
|
+ ): TreeNode<T>[] {
|
|
|
|
|
+ const rst: TreeNode<T>[] = [];
|
|
|
|
|
+ const pushNodes = (nodes: TreeNode<T>[]): void => {
|
|
|
nodes.forEach(node => {
|
|
nodes.forEach(node => {
|
|
|
if (includeSelf || !treeNodes.includes(node)) {
|
|
if (includeSelf || !treeNodes.includes(node)) {
|
|
|
rst.push(node);
|
|
rst.push(node);
|
|
@@ -233,7 +234,7 @@ export class Tree<T = any> {
|
|
|
|
|
|
|
|
// 节选中点块是否是可操作的节点块,选中一批节点进行升降、上下移的时候可能需要用到这个判断。
|
|
// 节选中点块是否是可操作的节点块,选中一批节点进行升降、上下移的时候可能需要用到这个判断。
|
|
|
// 以第一个节点为基准,如果后续的节点深度均大于于于等于第一个节点的深度,且节点间是连续的,则此为可操作节点块
|
|
// 以第一个节点为基准,如果后续的节点深度均大于于于等于第一个节点的深度,且节点间是连续的,则此为可操作节点块
|
|
|
- isOperable(nodes: (TreeNode & T)[]): boolean {
|
|
|
|
|
|
|
+ isOperable(nodes: TreeNode<T>[]): boolean {
|
|
|
const baseDepth = nodes[0].getCtx().depth();
|
|
const baseDepth = nodes[0].getCtx().depth();
|
|
|
for (let i = 0; i < nodes.length; i++) {
|
|
for (let i = 0; i < nodes.length; i++) {
|
|
|
const node = nodes[i];
|
|
const node = nodes[i];
|
|
@@ -253,7 +254,7 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 从节点块中获取相同深度的节点
|
|
// 从节点块中获取相同深度的节点
|
|
|
- sameDepthNodes(nodes: (TreeNode & T)[], depth?: number): (TreeNode & T)[] {
|
|
|
|
|
|
|
+ sameDepthNodes(nodes: TreeNode<T>[], depth?: number): TreeNode<T>[] {
|
|
|
if (!depth) {
|
|
if (!depth) {
|
|
|
depth = nodes[0].getCtx().depth();
|
|
depth = nodes[0].getCtx().depth();
|
|
|
}
|
|
}
|
|
@@ -264,7 +265,7 @@ export class Tree<T = any> {
|
|
|
// 可调用完此方法后,将需要更新、插入的数据提交至数据库,成功响应后调用插入节点更新缓存的方法
|
|
// 可调用完此方法后,将需要更新、插入的数据提交至数据库,成功响应后调用插入节点更新缓存的方法
|
|
|
prepareInsert(rawData: TreeRaw[]): UpdateData[] {
|
|
prepareInsert(rawData: TreeRaw[]): UpdateData[] {
|
|
|
const updateData: UpdateData[] = [];
|
|
const updateData: UpdateData[] = [];
|
|
|
- const insertParentMap: ParentMap = {};
|
|
|
|
|
|
|
+ const insertParentMap: ParentMap<T> = {};
|
|
|
// 将相同父项的插入数据和已存在数据进行合并
|
|
// 将相同父项的插入数据和已存在数据进行合并
|
|
|
rawData.forEach(item => {
|
|
rawData.forEach(item => {
|
|
|
if (typeof item.seq === 'undefined') {
|
|
if (typeof item.seq === 'undefined') {
|
|
@@ -274,7 +275,7 @@ export class Tree<T = any> {
|
|
|
insertParentMap[item.parentID] || (insertParentMap[item.parentID] = [])
|
|
insertParentMap[item.parentID] || (insertParentMap[item.parentID] = [])
|
|
|
).push(item);
|
|
).push(item);
|
|
|
});
|
|
});
|
|
|
- const combineMap: ParentMap = {};
|
|
|
|
|
|
|
+ const combineMap: ParentMap<T> = {};
|
|
|
Object.entries(insertParentMap).forEach(([parentID, insertItems]) => {
|
|
Object.entries(insertParentMap).forEach(([parentID, insertItems]) => {
|
|
|
const items = this.parentMap[parentID];
|
|
const items = this.parentMap[parentID];
|
|
|
combineMap[parentID] = [...insertParentMap[parentID]];
|
|
combineMap[parentID] = [...insertParentMap[parentID]];
|
|
@@ -283,7 +284,7 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
// 重新排序
|
|
// 重新排序
|
|
|
const combineItems = combineMap[parentID];
|
|
const combineItems = combineMap[parentID];
|
|
|
- Tree.sort(combineItems);
|
|
|
|
|
|
|
+ this.sort(combineItems as any);
|
|
|
combineItems.forEach((item, index) => {
|
|
combineItems.forEach((item, index) => {
|
|
|
// 插入数据重新赋值
|
|
// 插入数据重新赋值
|
|
|
if (insertItems.includes(item)) {
|
|
if (insertItems.includes(item)) {
|
|
@@ -303,7 +304,7 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 插入节点数据
|
|
// 插入节点数据
|
|
|
- insert(items: TreeRaw[], updateData: UpdateData[] = []): (TreeNode & T)[] {
|
|
|
|
|
|
|
+ insert(items: TreeRaw[], updateData: UpdateData[] = []): TreeNode<T>[] {
|
|
|
// 更新需要更新的节点(一般为更新seq)
|
|
// 更新需要更新的节点(一般为更新seq)
|
|
|
this.updateValue(updateData);
|
|
this.updateValue(updateData);
|
|
|
// 建立映射、插入数据
|
|
// 建立映射、插入数据
|
|
@@ -316,21 +317,20 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 准备删除,返回所有需要删除的节点,包括嵌套节点
|
|
// 准备删除,返回所有需要删除的节点,包括嵌套节点
|
|
|
- prepareDelete(deleteNodes: (TreeNode & T)[]): (TreeNode & T)[] {
|
|
|
|
|
|
|
+ prepareDelete(deleteNodes: TreeNode<T>[]): TreeNode<T>[] {
|
|
|
return this.getNodesPosterity(deleteNodes);
|
|
return this.getNodesPosterity(deleteNodes);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 删除节点
|
|
* 删除节点
|
|
|
- * @param {(TreeNode & T)[]} treeNodes - 要删除的节点,不需要包含嵌套节点
|
|
|
|
|
- * @return {(TreeNode & T)[]} 返回被删除的节点
|
|
|
|
|
|
|
+ * @param treeNodes - 要删除的节点,不需要包含嵌套节点
|
|
|
*/
|
|
*/
|
|
|
- delete(treeNodes: (TreeNode & T)[]): (TreeNode & T)[] {
|
|
|
|
|
- const allDeletedNodes: (TreeNode & T)[] = [];
|
|
|
|
|
|
|
+ delete(treeNodes: TreeNode<T>[]): TreeNode<T>[] {
|
|
|
|
|
+ const allDeletedNodes: TreeNode<T>[] = [];
|
|
|
// 递归删除节点
|
|
// 递归删除节点
|
|
|
- const deleteNodes = (nodes: (TreeNode & T)[]): void => {
|
|
|
|
|
|
|
+ const deleteNodes = (nodes: TreeNode<T>[]): void => {
|
|
|
// 删除映射、删除数据
|
|
// 删除映射、删除数据
|
|
|
- const toDels: { nodes: TreeNode[]; delNode: TreeNode }[] = [];
|
|
|
|
|
|
|
+ const toDels: { nodes: TreeNode<T>[]; delNode: TreeNode<T> }[] = [];
|
|
|
nodes.forEach(node => {
|
|
nodes.forEach(node => {
|
|
|
allDeletedNodes.push(node);
|
|
allDeletedNodes.push(node);
|
|
|
delete this.IDMap[node.ID];
|
|
delete this.IDMap[node.ID];
|
|
@@ -371,8 +371,8 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// IDList 返回所有需要删除的节点,包括嵌套节点
|
|
// IDList 返回所有需要删除的节点,包括嵌套节点
|
|
|
- prepareDeleteByID(IDList: string[]): (TreeNode & T)[] {
|
|
|
|
|
- const deleteNodes: (TreeNode & T)[] = [];
|
|
|
|
|
|
|
+ prepareDeleteByID(IDList: string[]): TreeNode<T>[] {
|
|
|
|
|
+ const deleteNodes: TreeNode<T>[] = [];
|
|
|
IDList.forEach(ID => {
|
|
IDList.forEach(ID => {
|
|
|
const node = this.find(ID);
|
|
const node = this.find(ID);
|
|
|
if (node) {
|
|
if (node) {
|
|
@@ -384,11 +384,10 @@ export class Tree<T = any> {
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 根据ID删除节点
|
|
* 根据ID删除节点
|
|
|
- * @param {string[]} IDList - 要删除的节点的ID列表(不包含嵌套节点ID)
|
|
|
|
|
- * @return {TreeNode[]} - 返回被删除的所有节点
|
|
|
|
|
|
|
+ * @param IDList - 要删除的节点的ID列表(不包含嵌套节点ID)
|
|
|
*/
|
|
*/
|
|
|
- deleteByID(IDList: string[]): (TreeNode & T)[] {
|
|
|
|
|
- const deleteNodes: (TreeNode & T)[] = [];
|
|
|
|
|
|
|
+ deleteByID(IDList: string[]): TreeNode<T>[] {
|
|
|
|
|
+ const deleteNodes: TreeNode<T>[] = [];
|
|
|
IDList.forEach(ID => {
|
|
IDList.forEach(ID => {
|
|
|
const node = this.find(ID);
|
|
const node = this.find(ID);
|
|
|
if (node) {
|
|
if (node) {
|
|
@@ -400,7 +399,7 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 准备上移节点块(连续的兄弟节点),注意节点的seq可能不连号
|
|
// 准备上移节点块(连续的兄弟节点),注意节点的seq可能不连号
|
|
|
- prepareUpMove(nodes: (TreeNode & T)[]): UpdateData[] {
|
|
|
|
|
|
|
+ prepareUpMove(nodes: TreeNode<T>[]): UpdateData[] {
|
|
|
const updateData: UpdateData[] = [];
|
|
const updateData: UpdateData[] = [];
|
|
|
const firstNode = nodes[0];
|
|
const firstNode = nodes[0];
|
|
|
const firstNodePrev = this.findPrev(firstNode.ID);
|
|
const firstNodePrev = this.findPrev(firstNode.ID);
|
|
@@ -424,7 +423,7 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 准备下移节点块(连续的兄弟节点),注意节点的seq可能不连号
|
|
// 准备下移节点块(连续的兄弟节点),注意节点的seq可能不连号
|
|
|
- prepareDownMove(nodes: (TreeNode & T)[]): UpdateData[] {
|
|
|
|
|
|
|
+ prepareDownMove(nodes: TreeNode<T>[]): UpdateData[] {
|
|
|
const updateData: UpdateData[] = [];
|
|
const updateData: UpdateData[] = [];
|
|
|
const lastNode = nodes[nodes.length - 1];
|
|
const lastNode = nodes[nodes.length - 1];
|
|
|
const lastNodeNext = this.findNext(lastNode.ID);
|
|
const lastNodeNext = this.findNext(lastNode.ID);
|
|
@@ -449,13 +448,13 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 上下移
|
|
// 上下移
|
|
|
- move(nodes: (TreeNode & T)[], updateData: UpdateData[]): void {
|
|
|
|
|
|
|
+ move(nodes: TreeNode<T>[], updateData: UpdateData[]): void {
|
|
|
this.updateValue(updateData);
|
|
this.updateValue(updateData);
|
|
|
this.reSortData(nodes);
|
|
this.reSortData(nodes);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 准备升级节点块(连续的兄弟节点),不维护seq连号
|
|
// 准备升级节点块(连续的兄弟节点),不维护seq连号
|
|
|
- prepareUpLevel(nodes: (TreeNode & T)[]): UpdateData[] {
|
|
|
|
|
|
|
+ prepareUpLevel(nodes: TreeNode<T>[]): UpdateData[] {
|
|
|
const updateData: UpdateData[] = [];
|
|
const updateData: UpdateData[] = [];
|
|
|
const firstNode = nodes[0];
|
|
const firstNode = nodes[0];
|
|
|
const lastNode = nodes[nodes.length - 1];
|
|
const lastNode = nodes[nodes.length - 1];
|
|
@@ -495,7 +494,7 @@ export class Tree<T = any> {
|
|
|
return updateData;
|
|
return updateData;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- upLevel(nodes: (TreeNode & T)[], updateData: UpdateData[]): void {
|
|
|
|
|
|
|
+ upLevel(nodes: TreeNode<T>[], updateData: UpdateData[]): void {
|
|
|
const firstNode = nodes[0];
|
|
const firstNode = nodes[0];
|
|
|
const lastNode = nodes[nodes.length - 1];
|
|
const lastNode = nodes[nodes.length - 1];
|
|
|
if (!firstNode.getCtx().canUpLevel()) {
|
|
if (!firstNode.getCtx().canUpLevel()) {
|
|
@@ -516,7 +515,7 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 准备降级节点块(连续的兄弟节点),不维护seq连号
|
|
// 准备降级节点块(连续的兄弟节点),不维护seq连号
|
|
|
- prepareDownLevel(nodes: (TreeNode & T)[]): UpdateData[] {
|
|
|
|
|
|
|
+ prepareDownLevel(nodes: TreeNode<T>[]): UpdateData[] {
|
|
|
const updateData: UpdateData[] = [];
|
|
const updateData: UpdateData[] = [];
|
|
|
const firstNode = nodes[0];
|
|
const firstNode = nodes[0];
|
|
|
const prevNode = this.findPrev(firstNode.ID);
|
|
const prevNode = this.findPrev(firstNode.ID);
|
|
@@ -537,7 +536,7 @@ export class Tree<T = any> {
|
|
|
return updateData;
|
|
return updateData;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- downLevel(nodes: (TreeNode & T)[], updateData: UpdateData[]): void {
|
|
|
|
|
|
|
+ downLevel(nodes: TreeNode<T>[], updateData: UpdateData[]): void {
|
|
|
const firstNode = nodes[0];
|
|
const firstNode = nodes[0];
|
|
|
if (!firstNode.getCtx().canDownLevel()) {
|
|
if (!firstNode.getCtx().canDownLevel()) {
|
|
|
return;
|
|
return;
|
|
@@ -558,12 +557,12 @@ export class Tree<T = any> {
|
|
|
|
|
|
|
|
// 准备移动节点块(连续的兄弟节点),不维护seq连号
|
|
// 准备移动节点块(连续的兄弟节点),不维护seq连号
|
|
|
prepareMoveTo(
|
|
prepareMoveTo(
|
|
|
- nodes: (TreeNode & T)[],
|
|
|
|
|
- parent: (TreeNode & T) | None,
|
|
|
|
|
- next: (TreeNode & T) | None
|
|
|
|
|
|
|
+ nodes: TreeNode<T>[],
|
|
|
|
|
+ parent: TreeNode<T> | None,
|
|
|
|
|
+ next: TreeNode<T> | None
|
|
|
): UpdateData[] {
|
|
): UpdateData[] {
|
|
|
const updateData: UpdateData[] = [];
|
|
const updateData: UpdateData[] = [];
|
|
|
- let prev: (TreeNode & T) | null;
|
|
|
|
|
|
|
+ let prev: TreeNode<T> | null;
|
|
|
if (next) {
|
|
if (next) {
|
|
|
prev = next.getCtx().prev();
|
|
prev = next.getCtx().prev();
|
|
|
} else {
|
|
} else {
|
|
@@ -601,8 +600,8 @@ export class Tree<T = any> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
moveTo(
|
|
moveTo(
|
|
|
- nodes: (TreeNode & T)[],
|
|
|
|
|
- parent: (TreeNode & T) | None,
|
|
|
|
|
|
|
+ nodes: TreeNode<T>[],
|
|
|
|
|
+ parent: TreeNode<T> | None,
|
|
|
updateData: UpdateData[]
|
|
updateData: UpdateData[]
|
|
|
): void {
|
|
): void {
|
|
|
const firstNode = nodes[0];
|
|
const firstNode = nodes[0];
|