@@ -2,74 +2,61 @@ export function searchById(id) {
2
2
return ( item ) => item . id === id ;
3
3
}
4
4
5
+ interface BaseProps {
6
+ id ?: number ;
7
+
8
+ [ key : string ] : any ;
9
+ }
10
+
5
11
export interface IIndex < T > {
6
12
id ?: number ;
7
13
node ?: T ;
8
14
parent ?: number ;
9
- prev ?: number ;
10
- next ?: number ;
15
+ prev ?: number | null ;
16
+ next ?: number | null ;
11
17
[ x : string ] : any ; // default: children: []
12
18
}
13
19
export interface IIndexs < T > {
14
- [ index : number ] : IIndex < T > ;
20
+ [ index : string ] : IIndex < T > ;
15
21
}
16
- export interface ITreeInterface < T = any > {
22
+ export interface ITreeInterface < T extends BaseProps > {
17
23
count : number ;
18
24
obj : T ;
19
25
indexes : IIndexs < T > ;
20
26
childNodeName : string ;
21
27
}
22
28
23
- export interface ITreeInstance < T = any > {
24
- count : number ;
25
- obj : T ;
26
- indexes : IIndexs < T > ;
27
- childNodeName : string ;
28
- generate : ( obj ) => void ;
29
- getIndex : ( index : number ) => void ;
30
- removeIndex : ( index : number ) => void ;
31
- get : ( id : number ) => void ;
32
- remove : ( id : number ) => void ;
33
- update : ( id : number , extra ) => void ;
34
- updateChildren : ( children : IIndex < T > ) => void ;
35
- insert : ( obj : T , parentId : number , i : number ) => void ;
36
- insertBefore : ( obj : T , destId : number ) => void ;
37
- insertAfter : ( obj : T , destId : number ) => void ;
38
- prepend : ( obj : T , destId : number ) => void ;
39
- append : ( obj : T , destId : number ) => void ;
40
- }
41
-
42
- export class TreeViewUtil < T = any > implements ITreeInterface < T > {
29
+ export class TreeViewUtil < T extends BaseProps > implements ITreeInterface < T > {
43
30
count : number ;
44
31
obj : T ;
45
32
indexes : IIndexs < T > ;
46
33
childNodeName : string ;
47
34
48
35
/**
49
- *
50
- * @param obj // tree object
51
- * @param childNodeName // loop properties
52
- * @example indexes data structure example:
36
+ *
37
+ * indexes data structure example:
38
+ * ```ts
53
39
* {
54
- [2]: {
55
- id: 2,
56
- node: {},
57
- parent: 1,
58
- prev: null,
59
- next: 3
60
- },
61
- ...
62
- }
40
+ * [2]: {
41
+ * id: 2,
42
+ * node: {},
43
+ * parent: 1,
44
+ * prev: null,
45
+ * next: 3
46
+ * },
47
+ * ...
48
+ * }
49
+ * ```
63
50
*/
64
- constructor ( obj ?, childNodeName = 'children' ) {
51
+ constructor ( obj ?: T , childNodeName = 'children' ) {
65
52
this . count = 1 ; // nodes count
66
- this . obj = obj || { [ childNodeName ] : [ ] } ;
53
+ this . obj = obj || ( { [ childNodeName ] : [ ] } as any ) ;
67
54
this . indexes = { } ;
68
55
this . childNodeName = childNodeName ;
69
56
this . generate ( this . obj ) ;
70
57
}
71
58
72
- generate ( obj ) {
59
+ generate ( obj : T ) {
73
60
const indexes = this . indexes ;
74
61
const startId = obj . id ;
75
62
const self = this ;
@@ -114,19 +101,16 @@ export class TreeViewUtil<T = any> implements ITreeInterface<T> {
114
101
getIndex ( id : number ) {
115
102
const index = this . indexes [ id + '' ] ;
116
103
if ( index ) return index ;
104
+ return null ;
117
105
}
118
106
119
- removeIndex ( index : number ) {
120
- const self = this ;
121
- del ( index ) ;
122
-
123
- function del ( index ) {
124
- delete self . indexes [ index . id + '' ] ;
125
- if ( index [ self . childNodeName ] ?. length ) {
126
- index [ self . childNodeName ] . forEach ( function ( child ) {
127
- del ( self . getIndex ( child ) ) ;
128
- } ) ;
129
- }
107
+ removeIndex ( index : IIndex < T > ) {
108
+ delete this . indexes [ index . id + '' ] ;
109
+ if ( index [ this . childNodeName ] ?. length ) {
110
+ index [ this . childNodeName ] . forEach ( ( child ) => {
111
+ const childIndex = this . getIndex ( child ) ;
112
+ childIndex && this . removeIndex ( childIndex ) ;
113
+ } ) ;
130
114
}
131
115
}
132
116
@@ -138,87 +122,114 @@ export class TreeViewUtil<T = any> implements ITreeInterface<T> {
138
122
139
123
remove ( id : number ) {
140
124
const index = this . getIndex ( id ) ;
141
- const node = this . get ( id ) ;
142
- const parentIndex = this . getIndex ( index . parent ) ;
143
- const parentNode = this . get ( index . parent ) ;
144
-
145
- parentNode [ this . childNodeName ] . splice (
146
- parentNode [ this . childNodeName ] . indexOf ( node ) ,
147
- 1
148
- ) ;
149
- parentIndex [ this . childNodeName ] . splice (
150
- parentIndex [ this . childNodeName ] . indexOf ( id ) ,
151
- 1
152
- ) ;
153
- this . removeIndex ( index ) ;
154
- this . updateChildren ( parentIndex [ this . childNodeName ] ) ;
155
-
156
- return node ;
125
+ if ( index ) {
126
+ const node = this . get ( id ) ;
127
+ const parentIndex = this . getIndex ( index . parent ! ) ;
128
+ const parentNode = this . get ( index . parent ! ) ;
129
+
130
+ if ( parentNode && parentIndex ) {
131
+ parentNode [ this . childNodeName ] . splice (
132
+ parentNode [ this . childNodeName ] . indexOf ( node ) ,
133
+ 1
134
+ ) ;
135
+ parentIndex [ this . childNodeName ] . splice (
136
+ parentIndex [ this . childNodeName ] . indexOf ( id ) ,
137
+ 1
138
+ ) ;
139
+ this . removeIndex ( index ) ;
140
+ this . updateChildren ( parentIndex [ this . childNodeName ] ) ;
141
+
142
+ return node ;
143
+ }
144
+ }
145
+ return null ;
157
146
}
158
147
159
148
update ( id : number , extra = { } ) {
160
149
const index = this . getIndex ( id ) ;
161
150
const node = this . get ( id ) ;
162
- const parentIndex = this . getIndex ( index . parent ) ;
163
- const parentNode = this . get ( index . parent ) ;
164
- parentNode [ this . childNodeName ] . splice (
165
- parentNode [ this . childNodeName ] . indexOf ( node ) ,
166
- 1 ,
167
- {
168
- ...node ,
169
- ...extra ,
151
+ if ( index ) {
152
+ const parentIndex = this . getIndex ( index . parent ! ) ;
153
+ const parentNode = this . get ( index . parent ! ) ;
154
+ if ( parentNode && parentIndex ) {
155
+ parentNode [ this . childNodeName ] . splice (
156
+ parentNode [ this . childNodeName ] . indexOf ( node ) ,
157
+ 1 ,
158
+ {
159
+ ...node ,
160
+ ...extra ,
161
+ }
162
+ ) ;
163
+ this . updateChildren ( parentIndex [ this . childNodeName ] ) ;
164
+ return node ;
170
165
}
171
- ) ;
172
- this . updateChildren ( parentIndex [ this . childNodeName ] ) ;
173
-
174
- return node ;
166
+ }
167
+ return null ;
175
168
}
176
169
177
170
updateChildren ( children : IIndex < T > ) {
178
171
const self = this ;
179
172
children . forEach ( function ( id , i ) {
180
173
const index = self . getIndex ( id ) ;
181
- index . prev = index . next = null ;
182
- if ( i > 0 ) index . prev = children [ i - 1 ] ;
183
- if ( i < children . length - 1 ) index . next = children [ i + 1 ] ;
174
+ if ( index ) {
175
+ index . prev = index . next = null ;
176
+ if ( i > 0 ) index . prev = children [ i - 1 ] ;
177
+ if ( i < children . length - 1 ) index . next = children [ i + 1 ] ;
178
+ }
184
179
} ) ;
185
180
}
186
181
187
182
insert ( obj : T , parentId : number , i : number ) {
188
183
const parentIndex = this . getIndex ( parentId ) ;
189
184
const parentNode = this . get ( parentId ) ;
185
+ if ( parentNode && parentIndex ) {
186
+ const index = this . generate ( obj ) ;
187
+ index . parent = parentId ;
188
+
189
+ ( parentNode as BaseProps ) [ this . childNodeName ] =
190
+ parentNode [ this . childNodeName ] || [ ] ;
191
+ parentIndex [ this . childNodeName ] =
192
+ parentIndex [ this . childNodeName ] || [ ] ;
193
+
194
+ parentNode [ this . childNodeName ] . splice ( i , 0 , obj ) ;
195
+ parentIndex [ this . childNodeName ] . splice ( i , 0 , index . id ) ;
196
+
197
+ this . updateChildren ( parentIndex [ this . childNodeName ] ) ;
198
+ if ( parentIndex . parent ) {
199
+ const fartherParent = this . getIndex ( parentIndex . parent ) ;
200
+ fartherParent &&
201
+ this . updateChildren ( fartherParent [ this . childNodeName ] ) ;
202
+ }
190
203
191
- const index = this . generate ( obj ) ;
192
- index . parent = parentId ;
193
-
194
- parentNode [ this . childNodeName ] = parentNode [ this . childNodeName ] || [ ] ;
195
- parentIndex [ this . childNodeName ] = parentIndex [ this . childNodeName ] || [ ] ;
196
-
197
- parentNode [ this . childNodeName ] . splice ( i , 0 , obj ) ;
198
- parentIndex [ this . childNodeName ] . splice ( i , 0 , index . id ) ;
199
-
200
- this . updateChildren ( parentIndex [ this . childNodeName ] ) ;
201
- if ( parentIndex . parent ) {
202
- this . updateChildren (
203
- this . getIndex ( parentIndex . parent ) [ this . childNodeName ]
204
- ) ;
204
+ return index ;
205
205
}
206
-
207
- return index ;
206
+ return null ;
208
207
}
209
208
210
209
insertBefore ( obj : T , destId : number ) {
211
210
const destIndex = this . getIndex ( destId ) ;
212
- const parentId = destIndex . parent ;
213
- const i = this . getIndex ( parentId ) [ this . childNodeName ] . indexOf ( destId ) ;
214
- return this . insert ( obj , parentId , i ) ;
211
+ if ( destIndex ) {
212
+ const parentId = destIndex . parent ;
213
+ const parent = this . getIndex ( parentId ! ) ;
214
+ if ( parent ) {
215
+ const i = parent [ this . childNodeName ] . indexOf ( destId ) ;
216
+ return this . insert ( obj , parentId ! , i ) ;
217
+ }
218
+ }
219
+ return null ;
215
220
}
216
221
217
222
insertAfter ( obj : T , destId : number ) {
218
223
const destIndex = this . getIndex ( destId ) ;
219
- const parentId = destIndex . parent ;
220
- const i = this . getIndex ( parentId ) [ this . childNodeName ] . indexOf ( destId ) ;
221
- return this . insert ( obj , parentId , i + 1 ) ;
224
+ if ( destIndex ) {
225
+ const parentId = destIndex . parent ;
226
+ const parent = this . getIndex ( parentId ! ) ;
227
+ if ( parent ) {
228
+ const i = parent [ this . childNodeName ] . indexOf ( destId ) ;
229
+ return this . insert ( obj , parentId ! , i + 1 ) ;
230
+ }
231
+ }
232
+ return null ;
222
233
}
223
234
224
235
prepend ( obj : T , destId : number ) {
@@ -227,7 +238,14 @@ export class TreeViewUtil<T = any> implements ITreeInterface<T> {
227
238
228
239
append ( obj : T , destId : number ) {
229
240
const destIndex = this . getIndex ( destId ) ;
230
- destIndex [ this . childNodeName ] = destIndex [ this . childNodeName ] || [ ] ;
231
- return this . insert ( obj , destId , destIndex [ this . childNodeName ] . length ) ;
241
+ if ( destIndex ) {
242
+ destIndex [ this . childNodeName ] = destIndex [ this . childNodeName ] || [ ] ;
243
+ return this . insert (
244
+ obj ,
245
+ destId ,
246
+ destIndex [ this . childNodeName ] . length
247
+ ) ;
248
+ }
249
+ return null ;
232
250
}
233
251
}
0 commit comments