@cloudbase/framework-plugin-low-code 0.7.31 → 0.7.34

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.
@@ -1,42 +1,101 @@
1
- import { observable, autorun, untracked } from 'mobx'
2
- import { styleToCss } from './style'
3
- import { getDeep } from './util'
4
- import { compLowcodes, create$comp } from './weapp-component'
1
+ import { observable, autorun, untracked } from 'mobx';
2
+ import { styleToCss } from './style';
3
+ import { getDeep } from './util';
4
+ import { compLowcodes, create$comp } from './weapp-component';
5
+ // import EventEmitter from './event-emitter';
6
+ import lodashSet from 'lodash.set';
7
+
8
+ function basePullAt(array, indexes) {
9
+ let length = array ? indexes.length : 0;
10
+ let lastIndex = length - 1;
11
+
12
+ // eslint-disable-next-line no-plusplus
13
+ while (length--) {
14
+ let index = indexes[length];
15
+ let previous;
16
+ if (length == lastIndex || index !== previous) {
17
+ previous = index;
18
+ Array.prototype.splice.call(array, index, 1);
19
+ }
20
+ }
21
+ return array;
22
+ }
23
+
24
+ function remove(array, predicate) {
25
+ const result = [];
26
+ if (!(array != null && array.length)) {
27
+ return result;
28
+ }
29
+ let index = -1;
30
+ const indexes = [];
31
+ const { length } = array;
32
+
33
+ while (++index < length) {
34
+ const value = array[index];
35
+ if (predicate(value, index, array)) {
36
+ result.push(value);
37
+ indexes.push(index);
38
+ }
39
+ }
40
+ basePullAt(array, indexes);
41
+ return result;
42
+ }
5
43
 
6
44
  /**
7
45
  * convert widget prop to data for wxml
8
46
  * @param {*} props
9
47
  */
10
48
  function resolveWidgetProp(props) {
11
- let { classList = [] } = props
12
- const data = {}
13
- Object.keys(props).forEach(key => {
49
+ let { classList = [] } = props;
50
+ const data = {};
51
+ Object.keys(props).forEach((key) => {
14
52
  if (props[key] instanceof Function || props[key] === undefined) {
15
- return
53
+ return;
16
54
  }
17
- data[key] = props[key]
18
- })
19
- data.style = styleToCss(props.style)
20
- data.className = classList.join ? classList.join(' ') : classList
21
- const extraProps = ['classList', '_forItems', '_disposers', 'children', 'parent', '_parentId', 'id', '_order', 'widgetType', '$comp']
22
- extraProps.map(prop => {
23
- delete data[prop]
24
- })
25
- return data
55
+ data[key] = props[key];
56
+ });
57
+ data.style = styleToCss(props.style);
58
+ data.className = classList.join ? classList.join(' ') : classList;
59
+ const extraProps = [
60
+ 'classList',
61
+ '_forItems',
62
+ '_disposers',
63
+ 'children',
64
+ 'parent',
65
+ '_parentId',
66
+ 'id',
67
+ '_order',
68
+ 'widgetType',
69
+ '$comp',
70
+ ];
71
+ extraProps.map((prop) => {
72
+ delete data[prop];
73
+ });
74
+ return data;
26
75
  }
27
76
 
28
77
  // widget prop -> wxml data
29
78
  export function resolveWidgetData(props) {
30
79
  if (!Array.isArray(props)) {
31
- return resolveWidgetProp(props)
80
+ return resolveWidgetProp(props);
32
81
  }
33
- return props.map(resolveWidgetData)
82
+ return props.map(resolveWidgetData);
34
83
  }
35
84
 
36
-
37
85
  export function createWidgets(widgetProps, dataBinds, widgetHolder, context, ownerMpInst) {
38
- const rootNode = createWidgetDataTree(widgetProps, dataBinds)
39
- return createSubWidgetTree(rootNode, widgetProps, dataBinds, ownerMpInst, widgetHolder, undefined, undefined, undefined, undefined, undefined, context)
86
+ const rootNode = createWidgetDataTree(widgetProps, dataBinds);
87
+ return createSubWidgetTree(
88
+ rootNode,
89
+ widgetProps,
90
+ dataBinds,
91
+ ownerMpInst,
92
+ widgetHolder,
93
+ {},
94
+ null,
95
+ [],
96
+ undefined,
97
+ context,
98
+ );
40
99
  }
41
100
 
42
101
  /**
@@ -45,61 +104,97 @@ export function createWidgets(widgetProps, dataBinds, widgetHolder, context, own
45
104
  * @param curForNode a component node or a virtual root tree node
46
105
  * @returns {widgets: {id1:[], id2}, rootWidget: {children: [], _disposers: [], ...otherProps}}
47
106
  */
48
- function createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, widgetHolder = {},
49
- index = 0, forItems = {}, ownerForWidgetHolder = null,
50
- failedBinds = [], defaultParent = { children: observable([]), _disposers: [] }, context = {}) {
51
- const indexPostfix = (forItems.lists || []).slice().reverse().map(list => idSeparator + list.currentIndex).join('')
107
+ function createSubWidgetTree(
108
+ curForNode,
109
+ widgetProps,
110
+ dataBinds,
111
+ ownerMpInst,
112
+ widgetHolder = {},
113
+ forItems = {},
114
+ ownerForWidgetHolder = null,
115
+ failedBinds = [],
116
+ defaultParent = { children: observable([]), _disposers: [] },
117
+ context = {},
118
+ ) {
119
+ const indexPostfix = (forItems.lists || [])
120
+ .slice()
121
+ .reverse()
122
+ .map((list) => idSeparator + list.currentIndex)
123
+ .join('');
52
124
 
53
125
  // traverse down the tree to set up all widgets
54
- dfsTree(curForNode, (node) => {
55
- const parentForWidgetArr = ownerForWidgetHolder && ownerForWidgetHolder[node.id] || []
56
- const existedWidget = index < parentForWidgetArr.length ? parentForWidgetArr[index] : null // try to reuse previous node when rerun for
126
+ dfsTree(curForNode, (node, parentNode, cache) => {
127
+ const parentForWidgetArr = ownerForWidgetHolder?.[node.id] || [];
128
+ const { _waForKey } = node.value;
129
+ const key = forItems.itemsById?.[node.id]?.[_waForKey];
130
+ const index = cache[parentNode?.id]
131
+ ? cache[parentNode.id].index
132
+ : parentForWidgetArr.findIndex((widget) => key && widget._key === key);
133
+ const existedWidget = index !== -1 ? parentForWidgetArr[index] : null; // try to reuse previous node when rerun for
134
+
135
+ if (existedWidget) {
136
+ cache[node.id] = {
137
+ index,
138
+ };
139
+ }
57
140
 
58
- if (node.forCount === curForNode.forCount) { // Leaf node
59
- let w = existedWidget
141
+ if (node.forCount === curForNode.forCount) {
142
+ // Leaf node
143
+ let w = existedWidget;
60
144
  if (!existedWidget) {
61
- const parentNode = node.parent
62
- let parentWidget = null
145
+ const parentNode = node.parent;
146
+ let parentWidget = null;
63
147
  if (parentNode) {
64
- parentWidget = widgetHolder[parentNode.id] || ownerForWidgetHolder[parentNode.id]
148
+ parentWidget = widgetHolder[parentNode.id] || ownerForWidgetHolder[parentNode.id];
65
149
  }
66
- w = createAWidget(widgetProps[node.id], node.id + indexPostfix, parentWidget, ownerMpInst)
150
+ w = createAWidget(widgetProps[node.id], node.id + indexPostfix, parentWidget, ownerMpInst);
151
+ w._key = key;
67
152
  if (!parentWidget) {
68
- defaultParent.children.push(w)
153
+ defaultParent.children.push(w);
69
154
  }
70
- parentForWidgetArr.push(w)
155
+ parentForWidgetArr.push(w);
71
156
  } else {
72
- disposeWidget(existedWidget, true)
157
+ disposeWidget(existedWidget, true);
73
158
  }
74
- setUpWidateDataBinds(w, dataBinds[node.id], forItems, failedBinds, context)
75
- widgetHolder[node.id] = w
159
+ setUpWidgetDataBinds(w, dataBinds[node.id], forItems, failedBinds, context);
160
+ widgetHolder[node.id] = w;
76
161
  } else if (!existedWidget) {
77
- const len = parentForWidgetArr.push(observable([]))
78
- widgetHolder[node.id] = parentForWidgetArr[len - 1]
162
+ const len = parentForWidgetArr.push(observable([]));
163
+ widgetHolder[node.id] = parentForWidgetArr[len - 1];
79
164
  } else {
80
165
  // Reuse existed for widget array
81
- widgetHolder[node.id] = existedWidget
166
+ widgetHolder[node.id] = existedWidget;
82
167
  }
83
- })
168
+ });
84
169
 
85
170
  // run for of next level
86
171
  dfsTree(curForNode, (node) => {
87
172
  if (node.forCount === curForNode.forCount + 1 && dataBinds[node.id] && dataBinds[node.id]._waFor) {
88
173
  // find the node bound with next level for
89
- const parent = node.parent ? widgetHolder[node.parent.id] : defaultParent
90
- const dispose = runFor(node, widgetProps, dataBinds, ownerMpInst, forItems, widgetHolder, failedBinds, parent, context)
91
- parent._disposers.push(dispose) // Add the for bind dispose to the parent node of forNode
174
+ const parent = node.parent ? widgetHolder[node.parent.id] : defaultParent;
175
+ const dispose = runFor(
176
+ node,
177
+ widgetProps,
178
+ dataBinds,
179
+ ownerMpInst,
180
+ forItems,
181
+ widgetHolder,
182
+ failedBinds,
183
+ parent,
184
+ context,
185
+ );
186
+ parent._disposers.push(dispose); // Add the for bind dispose to the parent node of forNode
92
187
  }
93
- })
188
+ });
94
189
 
95
190
  // Retry failed databinds
96
- const len = failedBinds.length
191
+ const len = failedBinds.length;
97
192
  for (let i = 0; i < len; i++) {
98
- const setUpDataBind = failedBinds.shift()
99
- setUpDataBind()
193
+ const setUpDataBind = failedBinds.shift();
194
+ setUpDataBind();
100
195
  }
101
196
 
102
- return { widgets: widgetHolder, rootWidget: widgetHolder[curForNode.id] || defaultParent }
197
+ return { widgets: widgetHolder, rootWidget: widgetHolder[curForNode.id] || defaultParent };
103
198
  }
104
199
 
105
200
  /**
@@ -110,123 +205,190 @@ function createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, wi
110
205
  * @param {*} parentWidget
111
206
  * @returns top level widgets or for dispose
112
207
  */
113
- function runFor(curForNode, widgetProps, dataBinds, ownerMpInst, forItems, ownerForWidgetHolder, failedBinds, defaultParent, context) {
114
- const nodeId = curForNode.id
208
+ const _FOR_ERROR_CACHE_MAP = {};
209
+ function runFor(
210
+ curForNode,
211
+ widgetProps,
212
+ dataBinds,
213
+ ownerMpInst,
214
+ forItems,
215
+ ownerForWidgetHolder,
216
+ failedBinds,
217
+ defaultParent,
218
+ context,
219
+ ) {
220
+ const nodeId = curForNode.id;
221
+ const { _waForKey } = curForNode.value;
222
+
115
223
  const dispose = autorun(() => {
116
- let forList = []
224
+ let forList = [];
117
225
  try {
118
- forList = dataBinds[nodeId]._waFor(forItems.lists, forItems.itemsById, undefined, context)
226
+ clearTimeout(_FOR_ERROR_CACHE_MAP[nodeId]);
227
+ forList = dataBinds[nodeId]._waFor(forItems.lists, forItems.itemsById, undefined, context);
119
228
  if (!Array.isArray(forList)) {
120
- forList = []
229
+ forList = [];
121
230
  }
122
231
  } catch (e) {
123
- forList = []
124
- console.warn('For binding error', e)
232
+ forList = [];
233
+ _FOR_ERROR_CACHE_MAP[nodeId] = setTimeout(() => {
234
+ console.warn('For binding error', nodeId, e);
235
+ }, 1000);
125
236
  }
126
237
 
127
238
  // Track list change (e.g. push)
128
- forList.forEach(e => { })
239
+ forList.forEach((e) => {});
129
240
 
130
241
  untracked(() => {
131
242
  // dispose widgets before reused instead
132
243
  // disposeWidgets(parentForWidgets[curForNode.id])
244
+ const exsitMap = forList.reduce((map, item) => {
245
+ if (item[_waForKey]) {
246
+ map[item[_waForKey]] = true;
247
+ }
248
+ return map;
249
+ }, {});
250
+ const forWidgets = ownerForWidgetHolder[nodeId];
251
+ const existedWidgetIndex = [];
252
+ const extraWidgetsIndex = [];
253
+ const extraWidgets = [];
254
+ forWidgets.forEach((widget, index) => {
255
+ if (exsitMap[widget._key]) {
256
+ existedWidgetIndex.push(index);
257
+ // need to use uqique key
258
+ exsitMap[widget._key] = undefined;
259
+ } else {
260
+ extraWidgetsIndex.push(index);
261
+ }
262
+ });
263
+ const extraWidgetsIndexMap = extraWidgetsIndex.reduce((map, item) => {
264
+ map[item] = true;
265
+ extraWidgets.push(forWidgets[item]);
266
+ return map;
267
+ }, {});
133
268
 
134
269
  // clean extra widgets of previous for run
135
270
  dfsTree(curForNode, (node) => {
136
- const arr = ownerForWidgetHolder[node.id]
137
- const extraWidgets = arr.splice(forList.length, arr.length)
138
- //console.log('@@ delete widgets', node.id, extraWidgets)
139
-
140
- if (node.id === curForNode.id) { // clean the root widget.children only(recursive)
141
- extraWidgets.map(w => {
142
- disposeWidget(w)
143
- const { children } = w.parent || defaultParent
144
- children.remove(w)
145
- // w.parent = null
146
- })
147
- }
148
- })
271
+ const arr = ownerForWidgetHolder[node.id];
272
+ remove(arr, (_, index) => {
273
+ return extraWidgetsIndexMap[index];
274
+ });
275
+ });
276
+
277
+ // 清理根 for 的 autorun, 并递归清理子节点
278
+ extraWidgets.map((w) => {
279
+ disposeWidget(w);
280
+ const { children } = w.parent || defaultParent;
281
+ children.remove(w);
282
+ // w.parent = null
283
+ });
149
284
 
150
285
  forList.forEach((item, index) => {
151
- let { lists = [], itemsById = {}, } = forItems
286
+ let { lists = [], itemsById = {} } = forItems;
152
287
  const _forItems = {
153
288
  lists: [{ currentItem: item, currentIndex: index }, ...lists],
154
- itemsById: { ...itemsById, [nodeId]: item },
155
- }
156
- const { rootWidget } = createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, {}, index, _forItems, ownerForWidgetHolder, failedBinds, defaultParent, context)
157
- rootWidget._forItems = _forItems
158
- })
159
- })
160
- })
161
-
162
- return dispose
289
+ itemsById: { ...itemsById, [nodeId]: item, index: { ...itemsById?.index, [nodeId]: index } },
290
+ };
291
+ const { rootWidget } = createSubWidgetTree(
292
+ curForNode,
293
+ widgetProps,
294
+ dataBinds,
295
+ ownerMpInst,
296
+ {},
297
+ _forItems,
298
+ ownerForWidgetHolder,
299
+ failedBinds,
300
+ defaultParent,
301
+ context,
302
+ );
303
+ rootWidget._forItems = _forItems;
304
+ });
305
+ });
306
+ });
307
+
308
+ return dispose;
163
309
  }
164
310
 
165
311
  function createAWidget(props, id, parent, ownerMpInst) {
166
-
167
- const w = observable(props)
312
+ const w = observable(props);
168
313
 
169
314
  // Builtin props
170
- Object.defineProperty(w, 'id', { value: id })
171
- const { widgetType } = w
172
- delete w.widgetType
173
- Object.defineProperty(w, 'widgetType', { value: widgetType })
174
-
175
- //w._disposers = []
176
- //w.children = []
177
- Object.defineProperty(w, 'children', { value: observable([]) })
178
- Object.defineProperty(w, '_disposers', { value: observable([]) })
315
+ Object.defineProperty(w, 'id', { value: id });
316
+ const { widgetType } = w;
317
+ delete w.widgetType;
318
+ Object.defineProperty(w, 'widgetType', { value: widgetType });
319
+
320
+ // w._disposers = []
321
+ // w.children = []
322
+ Object.defineProperty(w, 'children', { value: observable([]) });
323
+ Object.defineProperty(w, '_disposers', { value: observable([]) });
179
324
  if (parent) {
180
- //w.parent = parent
181
- Object.defineProperty(w, 'parent', { value: parent })
182
- parent.children.push(w)
325
+ // w.parent = parent
326
+ Object.defineProperty(w, 'parent', { value: parent });
327
+ parent.children.push(w);
183
328
  }
184
- delete w._parentId
329
+ delete w._parentId;
185
330
 
186
- Object.defineProperty(w, '$comp', { value: create$comp(w) })
187
- mountBuiltinWigetsAPI(w, ownerMpInst)
188
- return w
331
+ Object.defineProperty(w, '$comp', { value: create$comp(w) });
332
+ mountBuiltinWigetsAPI(w, ownerMpInst);
333
+ return w;
189
334
  }
190
335
 
191
- function setUpWidateDataBinds(w, dataBinds, forItems, failedBinds, context) {
192
- Object.keys(dataBinds || {}).map(prop => {
193
- if (prop === '_waFor') { return }
194
- const setUpDataBind = () => {
195
- let firstRunError = null
196
- const dispose = autorun(() => {
197
- try {
198
- // Computed data bind in the next tick since data bind may read widgets data
199
- w[prop] = dataBinds[prop](forItems.lists, forItems.itemsById, undefined, context)
200
- } catch (e) {
201
- if(prop === '_waIf'){
202
- w[prop] = false
203
- console.warn(`Error computing data bind ${w.id}.${prop}`, e)
204
- }else {
205
- // 吞错误,因为部分异步的属性刚开始没有,
206
- // 要求用户自己容错又要求太高,因此直接吞掉错误,只打印,不阻塞
207
- // firstRunError = e
208
- console.error(`Error computing data bind ${w.id}.${prop}`, e)
336
+ function setUpWidgetDataBinds(w, dataBinds, forItems, failedBinds, context) {
337
+ Object.keys(dataBinds || {})
338
+ .sort((a, b) => {
339
+ return a.length - b.length > 0 ? 1 : -1;
340
+ })
341
+ .map((prop) => {
342
+ if (prop === '_waFor') {
343
+ return;
344
+ }
345
+ let timer = null;
346
+ const setUpDataBind = (isFinalTry) => {
347
+ let firstRunError = null;
348
+ const dispose = autorun((reaction) => {
349
+ try {
350
+ clearTimeout(timer);
351
+ // Computed data bind in the next tick since data bind may read widgets data
352
+ const value = dataBinds[prop](forItems.lists, forItems.itemsById, undefined, context);
353
+ const paths = prop.split('.').filter((key) => !!key);
354
+ if (paths.length > 1) {
355
+ // 一定要 untracked 不然爆栈了
356
+ untracked(() => lodashSet(w, prop, value));
357
+ } else {
358
+ // 普通 key 直接赋值
359
+ w[prop] = value;
360
+ }
361
+ } catch (e) {
362
+ if (prop === '_waIf') {
363
+ w[prop] = false;
364
+ } else {
365
+ // 吞错误,因为部分异步的属性刚开始没有,
366
+ // 要求用户自己容错又要求太高,因此直接吞掉错误,只打印,不阻塞
367
+ // firstRunError = e
368
+ timer = setTimeout(() => {
369
+ console.warn(`Error computing data bind ${w.id}.${prop}`, e);
370
+ }, 1000);
371
+ }
209
372
  }
373
+ });
374
+ if (firstRunError) {
375
+ dispose();
376
+ failedBinds.push(setUpDataBind);
377
+ } else {
378
+ w._disposers.push(dispose);
210
379
  }
211
- })
212
- if (firstRunError) {
213
- dispose()
214
- failedBinds.push(setUpDataBind)
215
- } else {
216
- w._disposers.push(dispose)
217
- }
218
- }
219
- setUpDataBind()
220
- })
380
+ };
381
+ setUpDataBind();
382
+ });
221
383
  }
222
384
 
223
385
  export function findForItemsOfWidget(widget) {
224
- const forItems = widget._forItems
225
- if (forItems) return forItems
226
- if (widget.parent) return findForItemsOfWidget(widget.parent)
386
+ const forItems = widget._forItems;
387
+ if (forItems) return forItems;
388
+ if (widget.parent) return findForItemsOfWidget(widget.parent);
227
389
  }
228
390
 
229
- const idSeparator = '-'
391
+ const idSeparator = '-';
230
392
 
231
393
  /**
232
394
  *
@@ -234,148 +396,152 @@ const idSeparator = '-'
234
396
  * @param {*} comp Mp component instance or event.currentTarget, the component to convert
235
397
  */
236
398
  export function mpCompToWidget(owner, comp) {
237
- const { widgets } = owner.getWeAppInst()
238
- return getDeep(widgets, comp.id, idSeparator)
399
+ const { widgets } = owner.getWeAppInst();
400
+ return getDeep(widgets, comp.id, idSeparator);
239
401
  }
240
402
 
241
403
  /**
242
404
  * Add parent, children to widget
243
405
  */
244
406
  function createWidgetDataTree(widgets, dataBinds) {
245
- const virtualRoot = { children: [], forCount: 0 }
407
+ const virtualRoot = { children: [], forCount: 0 };
246
408
  const nodes = Object.keys(widgets).reduce((result, id) => {
247
- const w = widgets[id]
248
- result[id] = { id, value: w, _order: w._order, children: [], parent: null, forCount: 0 }
249
- delete w._order
250
- return result
251
- }, {})
409
+ const w = widgets[id];
410
+ result[id] = { id, value: w, _order: w._order, children: [], parent: null, forCount: 0 };
411
+ delete w._order;
412
+ return result;
413
+ }, {});
252
414
 
253
415
  // Create widgets tree API
254
- Object.keys(nodes).map(id => {
255
- const curNode = nodes[id]
256
- const parent = nodes[widgets[id]._parentId]
257
- //delete widgets[id]._parentId
416
+ Object.keys(nodes).map((id) => {
417
+ const curNode = nodes[id];
418
+ const parent = nodes[widgets[id]._parentId];
419
+ // delete widgets[id]._parentId
258
420
  if (!parent) {
259
- virtualRoot.children.push(curNode)
260
- return
421
+ virtualRoot.children.push(curNode);
422
+ return;
261
423
  }
262
- curNode.parent = parent
263
- parent.children.push(curNode)
264
- })
424
+ curNode.parent = parent;
425
+ parent.children.push(curNode);
426
+ });
265
427
 
266
428
  // Sort children
267
- Object.keys(nodes).map(id => {
268
- nodes[id].children.sort((a, b) => a._order - b._order)
269
- })
429
+ Object.keys(nodes).map((id) => {
430
+ nodes[id].children.sort((a, b) => a._order - b._order);
431
+ });
270
432
 
271
- virtualRoot.children.map(addForCount)
433
+ virtualRoot.children.map(addForCount);
272
434
 
273
435
  // dfs, add forCount
274
436
  function addForCount(node) {
275
437
  if (node.parent) {
276
- node.forCount = node.parent.forCount
438
+ node.forCount = node.parent.forCount;
277
439
  }
278
- if (dataBinds[node.id] && dataBinds[node.id]._waFor) {
279
- node.forCount++
440
+ if (dataBinds[node.id]?._waFor) {
441
+ node.forCount++;
280
442
  }
281
- node.children.map(addForCount)
443
+ node.children.map(addForCount);
282
444
  }
283
445
 
284
- return virtualRoot
446
+ return virtualRoot;
285
447
  }
286
448
 
287
- function dfsTree(node, fn, parent) {
288
- node.value && fn(node, parent)
289
- node.children.map(e => dfsTree(e, fn, node.value ? node : null))
449
+ function dfsTree(node, fn, parent, cache = {}) {
450
+ node.value && fn(node, parent, cache);
451
+ node.children.map((e) => dfsTree(e, fn, node.value ? node : null, cache));
290
452
  }
291
453
 
292
454
  // dispose autorun, widget can be the virtual root widget
293
455
  export function disposeWidget(widget, noRecursive) {
294
- const disposers = widget._disposers
295
- disposers.map(dispose => dispose())
296
- disposers.splice(0, disposers.length)
297
- !noRecursive && widget.children.forEach(w => disposeWidget(w))
456
+ const disposers = widget._disposers;
457
+ disposers.map((dispose) => dispose());
458
+ disposers.splice(0, disposers.length);
459
+ !noRecursive && widget.children.forEach((w) => disposeWidget(w));
298
460
  }
299
461
 
300
462
  export function createInitData(widgets, dataBinds, keyPrefix = '') {
301
463
  return Object.keys(widgets).reduce((result, id) => {
302
464
  if (!isWidgetInFor(id, widgets, dataBinds)) {
303
- result[keyPrefix + id] = resolveWidgetData(widgets[id])
465
+ result[keyPrefix + id] = resolveWidgetData(widgets[id]);
304
466
  }
305
- return result
306
- }, {})
467
+ return result;
468
+ }, {});
307
469
  }
308
470
 
309
471
  function isWidgetInFor(id, widgets, dataBinds) {
310
- let curNode = widgets[id]
311
- let nodeId = id
472
+ let curNode = widgets[id];
473
+ let nodeId = id;
312
474
  while (curNode) {
313
- if (dataBinds[nodeId] && dataBinds[nodeId]._waFor) {
314
- return true
475
+ if (dataBinds[nodeId]?._waFor) {
476
+ return true;
315
477
  }
316
- nodeId = curNode._parentId
317
- curNode = widgets[nodeId]
478
+ nodeId = curNode._parentId;
479
+ curNode = widgets[nodeId];
318
480
  }
319
481
  }
320
482
 
321
483
  function mountBuiltinWigetsAPI(widget, owner) {
322
484
  // #1 builtin APIs
323
485
  widget.findWidgets = function (filter, includeInvisibleDescendants) {
324
- let { children = [] } = this
325
- if (!includeInvisibleDescendants) { // include visible widgets only by default
326
- children = children.filter(e => e._waIf !== false)
486
+ let { children = [] } = this;
487
+ if (!includeInvisibleDescendants) {
488
+ // include visible widgets only by default
489
+ children = children.filter((e) => e._waIf !== false);
327
490
  }
328
- const matched = []
329
- children.forEach(w => {
491
+ const matched = [];
492
+ children.forEach((w) => {
330
493
  if (filter(w)) {
331
- matched.push(w)
494
+ matched.push(w);
332
495
  }
333
- matched.push(...w.findWidgets(filter, includeInvisibleDescendants))
334
- })
335
- return matched
336
- }
496
+ matched.push(...w.findWidgets(filter, includeInvisibleDescendants));
497
+ });
498
+ return matched;
499
+ };
337
500
 
338
501
  widget.getWidgetsByType = function (type, includeInvisibleDescendants) {
339
- return this.findWidgets(w => w.widgetType === type, includeInvisibleDescendants)
340
- }
502
+ return this.findWidgets((w) => w.widgetType === type, includeInvisibleDescendants);
503
+ };
341
504
 
342
505
  /**
343
506
  * Similar to selectOwnerComponent of WX MP: https://developers.weixin.qq.com/miniprogram/dev/reference/api/Component.html
344
507
  */
345
508
  widget.getOwnerWidget = function () {
346
- return owner && owner.getWeAppInst().node
347
- }
509
+ return owner?.getWeAppInst?.()?.node;
510
+ };
348
511
 
349
512
  // Will be overwritten by composited component
350
513
  widget.getDom = function (fields) {
351
514
  return new Promise((resolve, reject) => {
352
- const query = (owner || wx).createSelectorQuery()
353
- query.select('#' + this.id).fields(fields, res => {
354
- resolve(res)
355
- }).exec()
356
- })
357
- }
358
-
359
- widget.getConfig = () => ({})
360
-
361
- const lowcode = compLowcodes[widget.widgetType]
515
+ const query = (owner || wx).createSelectorQuery();
516
+ query
517
+ .select(`#${this.id}`)
518
+ .fields(fields, (res) => {
519
+ resolve(res);
520
+ })
521
+ .exec();
522
+ });
523
+ };
524
+
525
+ widget.getConfig = () => ({});
526
+
527
+ const lowcode = compLowcodes[widget.widgetType];
362
528
  if (lowcode) {
363
- const { index = {}, config } = lowcode
529
+ const { index = {}, config } = lowcode;
364
530
 
365
- widget.getConfig = () => config
531
+ widget.getConfig = () => config;
366
532
 
367
533
  // #2 User defined APIs
368
- const { publicMethods = {} } = index
369
- Object.keys(publicMethods).map(name => {
370
- const method = publicMethods[name]
534
+ const { publicMethods = {} } = index;
535
+ Object.keys(publicMethods).map((name) => {
536
+ const method = publicMethods[name];
371
537
  if (method instanceof Function) {
372
- Object.defineProperty(widget, name, { value: method.bind(widget.$comp) })
373
- Object.defineProperty(widget.$comp, name, { value: method })
538
+ Object.defineProperty(widget, name, { value: method.bind(widget.$comp) });
539
+ Object.defineProperty(widget.$comp, name, { value: method });
374
540
  } else {
375
- console.error(`Component(${widget.widgetType}) method(${name}) is not a function.`)
541
+ console.error(`Component(${widget.widgetType}) method(${name}) is not a function.`);
376
542
  }
377
- })
543
+ });
378
544
  }
379
545
 
380
- widget._methods = {}
546
+ widget._methods = {};
381
547
  }