@ticatec/uniface-element 0.3.15 → 0.3.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/TreeNode_README.md +577 -0
- package/dist/lib/TreeNode_README_CN.md +577 -0
- package/dist/lib/TreeNodes.d.ts +366 -45
- package/dist/lib/TreeNodes.js +394 -137
- package/dist/lib/index.d.ts +3 -4
- package/dist/lib/index.js +1 -2
- package/dist/list-box/index.d.ts +2 -2
- package/dist/list-box/types.d.ts +11 -1
- package/dist/nav-menu/Menus.d.ts +2 -2
- package/dist/nav-menu/Menus.js +6 -4
- package/dist/ticatec-uniface-web.css +29 -5
- package/dist/tree-view/README.md +143 -17
- package/dist/tree-view/README_CN.md +141 -1
- package/dist/tree-view/TreeNodeView.svelte +23 -9
- package/dist/tree-view/TreeNodeView.svelte.d.ts +5 -5
- package/dist/tree-view/TreeView.svelte +45 -5
- package/dist/tree-view/TreeView.svelte.d.ts +4 -2
- package/dist/tree-view/Types.d.ts +12 -8
- package/dist/tree-view/index.d.ts +3 -2
- package/package.json +1 -1
package/dist/lib/TreeNodes.js
CHANGED
|
@@ -1,7 +1,296 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 比较两个数字
|
|
3
|
+
* @param a 第一个数字
|
|
4
|
+
* @param b 第二个数字
|
|
5
|
+
* @returns 如果相等返回 0,a > b 返回 1,否则返回 -1
|
|
6
|
+
*/
|
|
1
7
|
export function compareNumber(a, b) {
|
|
2
8
|
return a === b ? 0 : a > b ? 1 : -1;
|
|
3
9
|
}
|
|
4
|
-
|
|
10
|
+
/**
|
|
11
|
+
* 节点视图配置类 - 定义节点的显示方式
|
|
12
|
+
* @template T 节点数据的类型
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* const options = new NodeViewOptions<MyData>({
|
|
16
|
+
* keyField: 'id',
|
|
17
|
+
* textField: 'name'
|
|
18
|
+
* });
|
|
19
|
+
*/
|
|
20
|
+
export class NodeViewOptions {
|
|
21
|
+
/**
|
|
22
|
+
* 获取节点的唯一标识字段
|
|
23
|
+
*/
|
|
24
|
+
keyField;
|
|
25
|
+
/**
|
|
26
|
+
* 获取节点的文字
|
|
27
|
+
* 可以是字段名或函数
|
|
28
|
+
*/
|
|
29
|
+
textField;
|
|
30
|
+
/**
|
|
31
|
+
* 创建节点视图配置
|
|
32
|
+
* @param options 配置选项
|
|
33
|
+
*/
|
|
34
|
+
constructor(options) {
|
|
35
|
+
this.keyField = options.keyField;
|
|
36
|
+
this.textField = options.textField;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 获取节点的文字
|
|
40
|
+
* @param data 节点数据
|
|
41
|
+
* @returns 显示文字
|
|
42
|
+
*/
|
|
43
|
+
getText(data) {
|
|
44
|
+
if (typeof this.textField === 'function') {
|
|
45
|
+
return this.textField(data);
|
|
46
|
+
}
|
|
47
|
+
return String(data[this.textField] ?? '');
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 获取节点的唯一标识
|
|
51
|
+
* @param data 节点数据
|
|
52
|
+
* @returns 唯一标识值
|
|
53
|
+
*/
|
|
54
|
+
getKey(data) {
|
|
55
|
+
return data[this.keyField];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* TreeNode 类 - 树节点,包含数据和方法
|
|
60
|
+
* @template T 节点数据的类型
|
|
61
|
+
*
|
|
62
|
+
* @description
|
|
63
|
+
* TreeNode 是树结构的基本单元,每个节点包含:
|
|
64
|
+
* - 节点数据(item)
|
|
65
|
+
* - 父节点引用(parent)
|
|
66
|
+
* - 子节点列表(children)
|
|
67
|
+
* - 展开状态(expand)
|
|
68
|
+
* - 加载状态(loading)
|
|
69
|
+
*
|
|
70
|
+
* 节点提供了丰富的操作方法,可以直接在节点上进行增删改查操作。
|
|
71
|
+
*/
|
|
72
|
+
export class TreeNode {
|
|
73
|
+
/**
|
|
74
|
+
* 节点数据(私有,只读)
|
|
75
|
+
* @private
|
|
76
|
+
*/
|
|
77
|
+
_item;
|
|
78
|
+
/**
|
|
79
|
+
* 节点层级(私有)
|
|
80
|
+
* @private
|
|
81
|
+
*/
|
|
82
|
+
_level;
|
|
83
|
+
/**
|
|
84
|
+
* 是否展开(显示子节点)
|
|
85
|
+
*/
|
|
86
|
+
expand = false;
|
|
87
|
+
/**
|
|
88
|
+
* 是否正在加载(用于懒加载)
|
|
89
|
+
*/
|
|
90
|
+
loading = false;
|
|
91
|
+
/**
|
|
92
|
+
* 父节点(只读)
|
|
93
|
+
*/
|
|
94
|
+
parent = null;
|
|
95
|
+
/**
|
|
96
|
+
* 子节点数组(私有)
|
|
97
|
+
* @private
|
|
98
|
+
*/
|
|
99
|
+
_children = null;
|
|
100
|
+
/**
|
|
101
|
+
* 创建树节点
|
|
102
|
+
* @param item 节点数据
|
|
103
|
+
* @param parent 父节点(可选)
|
|
104
|
+
* @param children 子节点列表(可选)
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* // 创建根节点
|
|
108
|
+
* const rootNode = new TreeNode({ id: 1, name: "根节点" });
|
|
109
|
+
*
|
|
110
|
+
* // 创建子节点
|
|
111
|
+
* const childNode = new TreeNode({ id: 2, name: "子节点" }, rootNode);
|
|
112
|
+
*/
|
|
113
|
+
constructor(item, parent = null, children = null) {
|
|
114
|
+
this._item = item;
|
|
115
|
+
this._level = parent ? parent._level + 1 : 0;
|
|
116
|
+
this.parent = parent;
|
|
117
|
+
this._children = children;
|
|
118
|
+
this.expand = false;
|
|
119
|
+
// 如果有父节点,将自己添加到父节点的 children 中
|
|
120
|
+
if (parent) {
|
|
121
|
+
if (!parent._children) {
|
|
122
|
+
parent._children = [];
|
|
123
|
+
}
|
|
124
|
+
parent._children.push(this);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* 获取节点层级
|
|
129
|
+
* @returns 层级值(根节点为 0)
|
|
130
|
+
*/
|
|
131
|
+
get level() {
|
|
132
|
+
return this._level;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* 获取子节点列表(只读)
|
|
136
|
+
* @returns 子节点数组的浅拷贝,如果没有子节点返回 null
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* const children = node.children;
|
|
140
|
+
* if (children) {
|
|
141
|
+
* children.forEach(child => console.log(child.item));
|
|
142
|
+
* }
|
|
143
|
+
*/
|
|
144
|
+
get children() {
|
|
145
|
+
return this._children ? [...this._children] : null;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 添加子节点
|
|
149
|
+
* @param childItem 子节点数据
|
|
150
|
+
* @returns 新创建的子节点
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* const childNode = parentNode.append({ id: 1, name: "子节点" });
|
|
154
|
+
*/
|
|
155
|
+
append(childItem) {
|
|
156
|
+
return new TreeNode(childItem, this);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* 从父节点中分离(删除当前节点)
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* node.detach();
|
|
163
|
+
*/
|
|
164
|
+
detach() {
|
|
165
|
+
if (!this.parent) {
|
|
166
|
+
console.warn('TreeNode is not attached to a tree, cannot detach');
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
this.parent.removeNode(this);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* 删除指定的子节点
|
|
173
|
+
* @param node 要删除的子节点
|
|
174
|
+
* @private
|
|
175
|
+
*/
|
|
176
|
+
removeNode(node) {
|
|
177
|
+
if (this._children) {
|
|
178
|
+
let idx = this._children.indexOf(node);
|
|
179
|
+
if (idx >= 0) {
|
|
180
|
+
this._children.splice(idx, 1);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
console.warn(' The removed node has not been attached to this.');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
console.warn(' The removed node has not been attached to this.');
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* 移动到另一个父节点下
|
|
192
|
+
* @param newParent 新的父节点
|
|
193
|
+
* @returns 新创建的节点(注意:返回的是新节点,不是原节点)
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* node.moveTo(newParentNode);
|
|
197
|
+
*/
|
|
198
|
+
moveTo(newParent) {
|
|
199
|
+
return new TreeNode(this._item, newParent, this._children);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* 替换当前节点的数据
|
|
203
|
+
* @param newItem 新的数据对象
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* node.replace({ id: 1, name: "新名称", ...otherFields });
|
|
207
|
+
*/
|
|
208
|
+
replace(newItem) {
|
|
209
|
+
this._item = newItem;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* 获取节点数据
|
|
213
|
+
* @returns 节点数据对象
|
|
214
|
+
*/
|
|
215
|
+
get item() {
|
|
216
|
+
return this._item;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* 删除所有子节点
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* node.removeChildren();
|
|
223
|
+
*/
|
|
224
|
+
removeChildren() {
|
|
225
|
+
this._children = [];
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* @internal 仅供 TreeNodes 内部使用
|
|
229
|
+
* 设置父节点,并将自己添加到父节点的 children 中
|
|
230
|
+
* @param parent 新的父节点
|
|
231
|
+
*
|
|
232
|
+
* @description
|
|
233
|
+
* 此方法会:
|
|
234
|
+
* 1. 从原父节点的 children 中移除自己
|
|
235
|
+
* 2. 更新父节点引用
|
|
236
|
+
* 3. 重新计算层级
|
|
237
|
+
* 4. 将自己添加到新父节点的 children 中
|
|
238
|
+
*/
|
|
239
|
+
_setParent(parent) {
|
|
240
|
+
// 从原父节点的 children 中移除自己
|
|
241
|
+
const oldParent = this.parent;
|
|
242
|
+
if (oldParent && oldParent._children) {
|
|
243
|
+
const index = oldParent._children.indexOf(this);
|
|
244
|
+
if (index >= 0) {
|
|
245
|
+
oldParent._children.splice(index, 1);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// 设置新父节点
|
|
249
|
+
this.parent = parent;
|
|
250
|
+
this._level = parent ? parent._level + 1 : 0;
|
|
251
|
+
// 将自己添加到新父节点的 children 中
|
|
252
|
+
if (parent) {
|
|
253
|
+
if (!parent._children) {
|
|
254
|
+
parent._children = [];
|
|
255
|
+
}
|
|
256
|
+
parent._children.push(this);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* TreeNodes 类 - 树节点管理器
|
|
262
|
+
* @template T 节点数据的类型
|
|
263
|
+
*
|
|
264
|
+
* @description
|
|
265
|
+
* TreeNodes 负责管理树结构的数据,包括:
|
|
266
|
+
* - 树的构建和初始化
|
|
267
|
+
* - 节点的映射和查找
|
|
268
|
+
* - 版本管理(用于响应式更新)
|
|
269
|
+
* - 层级展开控制
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* interface MyData {
|
|
273
|
+
* id: number;
|
|
274
|
+
* name: string;
|
|
275
|
+
* parentId: number | null;
|
|
276
|
+
* }
|
|
277
|
+
*
|
|
278
|
+
* const treeNodes = new TreeNodes<MyData>({
|
|
279
|
+
* keyField: 'id',
|
|
280
|
+
* textField: 'name',
|
|
281
|
+
* parentKeyField: 'parentId',
|
|
282
|
+
* checkIsRoot: (item) => item.parentId === null,
|
|
283
|
+
* checkIsDirectory: (node) => node.children !== null,
|
|
284
|
+
* expendDepth: 2
|
|
285
|
+
* });
|
|
286
|
+
*
|
|
287
|
+
* treeNodes.setData([
|
|
288
|
+
* { id: 1, name: "根节点", parentId: null },
|
|
289
|
+
* { id: 2, name: "子节点1", parentId: 1 },
|
|
290
|
+
* { id: 3, name: "子节点2", parentId: 1 }
|
|
291
|
+
* ]);
|
|
292
|
+
*/
|
|
293
|
+
export default class TreeNodes {
|
|
5
294
|
checkIsRoot;
|
|
6
295
|
keyField;
|
|
7
296
|
parentKeyField;
|
|
@@ -11,6 +300,11 @@ export class CommonTreeNodes {
|
|
|
11
300
|
compareFun;
|
|
12
301
|
expendDepth;
|
|
13
302
|
_nodes = [];
|
|
303
|
+
_version = 0;
|
|
304
|
+
/**
|
|
305
|
+
* 创建 TreeNodes 实例
|
|
306
|
+
* @param options 配置选项
|
|
307
|
+
*/
|
|
14
308
|
constructor(options) {
|
|
15
309
|
this.checkIsRoot = options.checkIsRoot;
|
|
16
310
|
this.compareFun = options.compareFun;
|
|
@@ -21,34 +315,77 @@ export class CommonTreeNodes {
|
|
|
21
315
|
this.expendDepth = options.expendDepth ?? 1;
|
|
22
316
|
this.checkIsDirectory = options.checkIsDirectory;
|
|
23
317
|
}
|
|
318
|
+
/**
|
|
319
|
+
* 设置树数据
|
|
320
|
+
* @param list 扁平化的节点数据数组
|
|
321
|
+
*
|
|
322
|
+
* @description
|
|
323
|
+
* 此方法会:
|
|
324
|
+
* 1. 清空现有树结构
|
|
325
|
+
* 2. 创建所有节点
|
|
326
|
+
* 3. 根据 parentKeyField 建立父子关系
|
|
327
|
+
* 4. 应用展开深度设置
|
|
328
|
+
* 5. 触发版本更新
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* treeNodes.setData([
|
|
332
|
+
* { id: 1, name: "根节点", parentId: null },
|
|
333
|
+
* { id: 2, name: "子节点1", parentId: 1 },
|
|
334
|
+
* { id: 3, name: "子节点2", parentId: 1 }
|
|
335
|
+
* ]);
|
|
336
|
+
*/
|
|
24
337
|
setData(list) {
|
|
25
338
|
this.nodeMap = new Map();
|
|
26
339
|
this._nodes = [];
|
|
27
|
-
//
|
|
340
|
+
// 第一遍:创建所有节点(不设置父子关系)
|
|
28
341
|
for (const item of list) {
|
|
29
|
-
const node = {
|
|
30
|
-
item,
|
|
31
|
-
expand: false
|
|
32
|
-
};
|
|
33
342
|
const key = item[this.keyField];
|
|
343
|
+
const node = new TreeNode(item); // 创建节点时不设置 parent
|
|
34
344
|
this.nodeMap.set(key, node);
|
|
35
345
|
}
|
|
346
|
+
// 第二遍:建立父子关系
|
|
36
347
|
for (const item of list) {
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
348
|
+
const key = item[this.keyField];
|
|
349
|
+
const node = this.nodeMap.get(key);
|
|
350
|
+
if (this.checkIsRoot(item)) {
|
|
351
|
+
// 是根节点
|
|
352
|
+
this._nodes.push(node);
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
// 不是根节点,找到父节点并建立关系
|
|
356
|
+
const parentKey = item[this.parentKeyField];
|
|
357
|
+
const parentNode = this.nodeMap.get(parentKey);
|
|
358
|
+
if (parentNode) {
|
|
359
|
+
// 使用 _setParent 方法建立父子关系
|
|
360
|
+
node._setParent(parentNode);
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
console.warn(`Parent node ${parentKey} not found for item ${key}, treating as root node`);
|
|
364
|
+
this._nodes.push(node);
|
|
365
|
+
}
|
|
40
366
|
}
|
|
41
367
|
}
|
|
42
|
-
|
|
43
|
-
|
|
368
|
+
// 应用展开深度设置
|
|
369
|
+
if (this.expendDepth > 0) {
|
|
370
|
+
this.setExpandForDepth(this._nodes, 0);
|
|
44
371
|
}
|
|
372
|
+
// 触发版本更新
|
|
373
|
+
this._version++;
|
|
45
374
|
}
|
|
46
375
|
/**
|
|
47
376
|
* 获取节点
|
|
48
377
|
*/
|
|
49
378
|
get nodes() {
|
|
379
|
+
// 通过访问 _version 让 Svelte 检测到变化
|
|
380
|
+
void this._version;
|
|
50
381
|
return this._nodes;
|
|
51
382
|
}
|
|
383
|
+
/**
|
|
384
|
+
* 获取版本号,用于触发 Svelte 响应式更新
|
|
385
|
+
*/
|
|
386
|
+
get version() {
|
|
387
|
+
return this._version;
|
|
388
|
+
}
|
|
52
389
|
/**
|
|
53
390
|
* 设置展开层级
|
|
54
391
|
* @param nodes
|
|
@@ -58,157 +395,77 @@ export class CommonTreeNodes {
|
|
|
58
395
|
setExpandForDepth(nodes, currentLevel) {
|
|
59
396
|
for (const node of nodes) {
|
|
60
397
|
node.expand = currentLevel < this.expendDepth;
|
|
61
|
-
if (node.
|
|
62
|
-
|
|
63
|
-
}
|
|
398
|
+
// if (node.getInternalChildren().length > 0) {
|
|
399
|
+
// this.setExpandForDepth(node.getInternalChildren(), currentLevel + 1);
|
|
400
|
+
// }
|
|
64
401
|
}
|
|
65
402
|
}
|
|
66
403
|
/**
|
|
67
|
-
*
|
|
68
|
-
* @param node
|
|
69
|
-
* @param doSort
|
|
70
|
-
* @protected
|
|
404
|
+
* 获取展开的展示列表
|
|
71
405
|
*/
|
|
72
|
-
|
|
73
|
-
let
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
parentNode.expand = true;
|
|
83
|
-
parentNode.children = [...(parentNode.children ?? []), node];
|
|
84
|
-
if (doSort && this.compareFun) {
|
|
85
|
-
parentNode.children = parentNode.children.sort(this.compareFun);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
console.warn('Ignore the isolate item:', item);
|
|
406
|
+
getHierarchyList() {
|
|
407
|
+
let arr = [];
|
|
408
|
+
this.addExpandNodesToList(this.nodes, arr);
|
|
409
|
+
return arr;
|
|
410
|
+
}
|
|
411
|
+
addExpandNodesToList(nodes, list) {
|
|
412
|
+
for (let node of nodes) {
|
|
413
|
+
list.push(node);
|
|
414
|
+
if (node.expand) {
|
|
415
|
+
this.addExpandNodesToList(node.children ?? [], list);
|
|
90
416
|
}
|
|
91
417
|
}
|
|
92
418
|
}
|
|
93
|
-
}
|
|
94
|
-
export default class TreeNodes extends CommonTreeNodes {
|
|
95
419
|
/**
|
|
96
|
-
*
|
|
420
|
+
* 不检测匹配情况,在指定的父节点下添加子节点
|
|
97
421
|
*/
|
|
98
|
-
|
|
99
|
-
|
|
422
|
+
batchAttachToParent(parent, list) {
|
|
423
|
+
let nodes = [];
|
|
424
|
+
for (let item of list) {
|
|
425
|
+
nodes.push(new TreeNode(item, parent));
|
|
426
|
+
}
|
|
427
|
+
return nodes;
|
|
100
428
|
}
|
|
101
429
|
/**
|
|
102
|
-
*
|
|
103
|
-
* @param
|
|
104
|
-
*/
|
|
105
|
-
/**
|
|
106
|
-
* 增加一个新节点
|
|
107
|
-
* @param item
|
|
430
|
+
* 增加一个新节点(便捷方法,会自动根据 parentKeyField 找到父节点)
|
|
431
|
+
* @param item 要添加的节点数据
|
|
108
432
|
*/
|
|
109
433
|
append(item) {
|
|
110
|
-
|
|
111
|
-
item
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* 替换一个节点的数据
|
|
119
|
-
* @param item
|
|
120
|
-
*/
|
|
121
|
-
replace(item) {
|
|
122
|
-
let node = this.nodeMap.get(item[this.keyField]);
|
|
123
|
-
if (node) {
|
|
124
|
-
node.item = item;
|
|
125
|
-
let parent = this.nodeMap.get(item[this.parentKeyField]);
|
|
126
|
-
if (parent && parent.children && parent.children.length > 0) {
|
|
127
|
-
parent.children = parent.children.sort(this.compareFun);
|
|
434
|
+
if (parent) {
|
|
435
|
+
if (this.checkIsRoot(item)) {
|
|
436
|
+
let node = new TreeNode(item);
|
|
437
|
+
this._nodes.push(node);
|
|
438
|
+
this._version++;
|
|
439
|
+
return node;
|
|
128
440
|
}
|
|
129
441
|
else {
|
|
130
|
-
|
|
442
|
+
throw new Error(`the entity is not a root data`);
|
|
131
443
|
}
|
|
132
444
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
this.nodeMap.delete(idKey);
|
|
140
|
-
if (parent) {
|
|
141
|
-
if (parent.children) {
|
|
142
|
-
let pos = parent.children.findIndex(el => el.item[this.keyField] == idKey);
|
|
143
|
-
if (pos > -1) {
|
|
144
|
-
parent.children.splice(pos, 1);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
445
|
+
else {
|
|
446
|
+
let parent = this.findParent(this.nodes, item);
|
|
447
|
+
if (!parent) {
|
|
448
|
+
let node = new TreeNode(item, parent);
|
|
449
|
+
this._version++;
|
|
450
|
+
return node;
|
|
147
451
|
}
|
|
148
452
|
else {
|
|
149
|
-
|
|
150
|
-
if (pos > -1) {
|
|
151
|
-
this._nodes.splice(pos, 1);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* 将一个节点移动到另外一个节点下
|
|
158
|
-
* @param item
|
|
159
|
-
* @param parentId
|
|
160
|
-
*/
|
|
161
|
-
moveTo(item, parentId) {
|
|
162
|
-
let newParent = this.nodeMap.get(parentId);
|
|
163
|
-
let node = this.nodeMap.get(item[this.keyField]);
|
|
164
|
-
let currentParent = this.nodeMap.get(item[this.parentKeyField]);
|
|
165
|
-
if (newParent && node && currentParent && currentParent.children) {
|
|
166
|
-
let pos = currentParent.children.findIndex(el => el.item[this.keyField] == item[this.keyField]);
|
|
167
|
-
if (pos > -1) {
|
|
168
|
-
currentParent.children.splice(pos, 1);
|
|
169
|
-
}
|
|
170
|
-
newParent.children = [...(newParent.children ?? []), node];
|
|
171
|
-
if (this.compareFun) {
|
|
172
|
-
newParent.children = newParent.children.sort(this.compareFun);
|
|
453
|
+
throw new Error(`cannot find the parent.`);
|
|
173
454
|
}
|
|
174
455
|
}
|
|
175
456
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
let list = [];
|
|
183
|
-
for (let node of nodes) {
|
|
184
|
-
if (node.item != item && this.checkIsDirectory?.(node)) {
|
|
185
|
-
list.push({
|
|
186
|
-
item: node.item,
|
|
187
|
-
expand: true,
|
|
188
|
-
children: getNodes(node.children ?? [], item)
|
|
189
|
-
});
|
|
457
|
+
findParent(nodes, item) {
|
|
458
|
+
let found = null;
|
|
459
|
+
for (const node of nodes) {
|
|
460
|
+
if (!found) {
|
|
461
|
+
if (node.item[this.keyField] == item[this.parentKeyField]) {
|
|
462
|
+
found = node;
|
|
190
463
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
};
|
|
194
|
-
return getNodes(this.nodes, exclusiveData);
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* 获取所有展开的节点
|
|
198
|
-
* @param tree
|
|
199
|
-
* @private
|
|
200
|
-
*/
|
|
201
|
-
collectExpandedNodes(tree) {
|
|
202
|
-
const result = [];
|
|
203
|
-
function traverse(nodes) {
|
|
204
|
-
for (const node of nodes) {
|
|
205
|
-
result.push(node);
|
|
206
|
-
if (node.expand && node.children) {
|
|
207
|
-
traverse(node.children);
|
|
464
|
+
else {
|
|
465
|
+
found = node.children && node.children.length > 0 ? this.findParent(node.children, item) : null;
|
|
208
466
|
}
|
|
209
467
|
}
|
|
210
468
|
}
|
|
211
|
-
|
|
212
|
-
return result;
|
|
469
|
+
return found;
|
|
213
470
|
}
|
|
214
471
|
}
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import TreeNodes from "./TreeNodes";
|
|
2
|
-
import type {
|
|
3
|
-
import { CommonTreeNodes } from "./TreeNodes";
|
|
2
|
+
import type { ITreeNode } from "./TreeNodes";
|
|
4
3
|
import type { CheckIsRoot, CompareFun, GetText, CheckIsDirectory, TreeNodeOptions } from "./TreeNodes";
|
|
5
4
|
import { compareNumber } from "./TreeNodes";
|
|
6
5
|
export default TreeNodes;
|
|
7
|
-
export {
|
|
8
|
-
export type {
|
|
6
|
+
export { compareNumber };
|
|
7
|
+
export type { ITreeNode };
|
|
9
8
|
export type { CheckIsRoot, CompareFun, GetText, CheckIsDirectory, TreeNodeOptions };
|
package/dist/lib/index.js
CHANGED
package/dist/list-box/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import ListBox from "./ListBox.svelte";
|
|
2
|
-
import type { LazyLoader, LoadResult, FunFilter } from "./types";
|
|
2
|
+
import type { ListLazyLoader, LazyLoader, LoadResult, FunFilter } from "./types";
|
|
3
3
|
export default ListBox;
|
|
4
|
-
export type { LazyLoader, FunFilter, LoadResult };
|
|
4
|
+
export type { ListLazyLoader, LazyLoader, FunFilter, LoadResult };
|
package/dist/list-box/types.d.ts
CHANGED
|
@@ -3,4 +3,14 @@ export interface LoadResult {
|
|
|
3
3
|
list: Array<any>;
|
|
4
4
|
}
|
|
5
5
|
export type FunFilter = (item: any, text: string) => boolean;
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* 分页加载列表数据
|
|
8
|
+
* @param text 搜索文本
|
|
9
|
+
* @param pageNo 页码(从0开始)
|
|
10
|
+
* @returns 加载结果,包含数据列表和是否有更多数据的标志
|
|
11
|
+
*/
|
|
12
|
+
export type ListLazyLoader = (text: string, pageNo: number) => Promise<LoadResult>;
|
|
13
|
+
/**
|
|
14
|
+
* @deprecated 使用 ListLazyLoader 代替。LazyLoader 已弃用,将在未来版本中移除。
|
|
15
|
+
*/
|
|
16
|
+
export type LazyLoader = ListLazyLoader;
|
package/dist/nav-menu/Menus.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import TreeNodes from "../lib/TreeNodes";
|
|
2
2
|
import type MenuItem from "./MenuItem";
|
|
3
|
-
export default class Menus extends
|
|
3
|
+
export default class Menus extends TreeNodes<MenuItem> {
|
|
4
4
|
/**
|
|
5
5
|
* 删除所有没有子节点的目录类型节点
|
|
6
6
|
*/
|
package/dist/nav-menu/Menus.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {} from "../lib/TreeNodes";
|
|
2
|
+
import TreeNodes from "../lib/TreeNodes";
|
|
3
|
+
export default class Menus extends TreeNodes {
|
|
3
4
|
/**
|
|
4
5
|
* 删除所有没有子节点的目录类型节点
|
|
5
6
|
*/
|
|
@@ -12,8 +13,9 @@ export default class Menus extends CommonTreeNodes {
|
|
|
12
13
|
}
|
|
13
14
|
else {
|
|
14
15
|
if (this.checkIsDirectory?.(node)) {
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
node.detach();
|
|
17
|
+
//nodes.splice(i, 1); // 从父节点的 children 中移除
|
|
18
|
+
//this.nodeMap.delete(node._item[this.keyField]); // 从 nodeMap 中移除
|
|
17
19
|
}
|
|
18
20
|
}
|
|
19
21
|
}
|