@cloudbase/lowcode-builder 1.3.9 → 1.3.11

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.
@@ -11,84 +11,84 @@ import { REPEATER } from './constant';
11
11
  * @param {*} props
12
12
  */
13
13
  const EXTRA_PROPS_MAP = [
14
- /**
15
- * create widgets
16
- */
17
- 'id',
18
- 'widgetType',
19
- 'parent',
20
- 'children',
21
- '_scope',
22
- '_disposers',
23
- '_eventListeners',
24
- /**
25
- * mount widget api
26
- */
27
- 'findWidgets',
28
- 'getWidgetsByType',
29
- 'getOwnerWidget',
30
- 'getDom',
31
- 'on',
32
- 'off',
33
- 'getConfig',
34
- '_getInstanceRef',
35
- '_methods',
36
- '_userWidget',
37
- /**
38
- * 其他挂载
39
- */
40
- '_descendants',
41
- '_forContext', // for root 挂载
42
- /**
43
- * widgetProps 附带值
44
- */
45
- // '_id',
46
- '_order',
47
- 'classList',
14
+ /**
15
+ * create widgets
16
+ */
17
+ 'id',
18
+ 'widgetType',
19
+ 'parent',
20
+ 'children',
21
+ '_scope',
22
+ '_disposers',
23
+ '_eventListeners',
24
+ /**
25
+ * mount widget api
26
+ */
27
+ 'findWidgets',
28
+ 'getWidgetsByType',
29
+ 'getOwnerWidget',
30
+ 'getDom',
31
+ 'on',
32
+ 'off',
33
+ 'getConfig',
34
+ '_getInstanceRef',
35
+ '_methods',
36
+ '_userWidget',
37
+ /**
38
+ * 其他挂载
39
+ */
40
+ '_descendants',
41
+ '_forContext', // for root 挂载
42
+ /**
43
+ * widgetProps 附带值
44
+ */
45
+ '_order',
46
+ 'classList',
48
47
  ].reduce((map, key) => {
49
- map[key] = true;
50
- return map;
48
+ map[key] = true;
49
+ return map;
51
50
  }, {});
52
51
 
53
52
  function resolveWidgetProp(props) {
54
- let { classList = [], ...restProps } = props;
55
- const data = {};
56
- Object.keys(restProps).forEach((key) => {
57
- if (EXTRA_PROPS_MAP[key]) {
58
- return;
59
- }
60
- if (restProps[key] instanceof Function || restProps[key] === undefined) {
61
- return;
62
- }
63
- data[key] = restProps[key];
64
- });
65
- data.style = styleToCss(restProps.style);
66
- data.className = classList.join ? classList.join(' ') : classList;
67
- return data;
53
+ let { classList = [], ...restProps } = props;
54
+ const data = {};
55
+ Object.keys(restProps).forEach((key) => {
56
+ if (EXTRA_PROPS_MAP[key]) {
57
+ return;
58
+ }
59
+ if (restProps[key] instanceof Function || restProps[key] === undefined) {
60
+ return;
61
+ }
62
+ data[key] = restProps[key];
63
+ });
64
+ data.style = styleToCss(restProps.style);
65
+ data.className = classList.join ? classList.join(' ') : classList;
66
+ return data;
68
67
  }
69
68
 
70
69
  // widget prop -> wxml data
71
70
  export function resolveWidgetData(props) {
72
- if (!Array.isArray(props)) {
73
- return resolveWidgetProp(props);
74
- }
75
- return props.map(resolveWidgetData);
71
+ if (!Array.isArray(props)) {
72
+ return resolveWidgetProp(props);
73
+ }
74
+ return props.map(resolveWidgetData);
76
75
  }
77
76
 
78
- export function createWidgets(widgetProps, dataBinds, ownerMpInst) {
79
- const rootNode = createWidgetDataTree(widgetProps, dataBinds);
80
- const failedBinds = [];
81
- const result = createSubWidgetTree(
82
- { ownerForWidgetHolder: {} },
83
- rootNode,
84
- dataBinds,
85
- ownerMpInst,
86
- {},
87
- failedBinds,
88
- undefined,
89
- );
90
- retryFailedBinds(failedBinds, true);
91
- return result;
77
+ export function createWidgets(widgetProps, dataBinds, ownerMpInst, widgetHolder) {
78
+ const rootNode = createWidgetDataTree(widgetProps, dataBinds);
79
+ const failedBinds = [];
80
+ const result = createSubWidgetTree(
81
+ { ownerForWidgetHolder: {} },
82
+ rootNode,
83
+ dataBinds,
84
+ ownerMpInst,
85
+ {},
86
+ failedBinds,
87
+ undefined,
88
+ widgetHolder
89
+ );
90
+ retryFailedBinds(failedBinds, true);
91
+ return result;
92
92
  }
93
93
 
94
94
  /**
@@ -98,130 +98,132 @@ return result;
98
98
  * @returns {widgets: {id1:[], id2}, rootWidget: {children: [], _disposers: [], ...otherProps}}
99
99
  */
100
100
  function createSubWidgetTree(
101
- ctx,
102
- curForNode,
103
- dataBinds,
104
- ownerMpInst,
105
- forContext = {},
106
- failedBinds = [],
107
- parentWidget = { children: observable([]), _disposers: [] },
108
- ) {
109
- const { ownerForWidgetHolder = {}, existingWidgetMap = {} } = ctx;
110
- /**
111
- * 不能类似web实现记录额外的 _disposers
112
- * const widgetHolder = { _disposers: [] }
113
- * 因为 merger-render.initMergeRenderer 里面没有特殊处理
114
- */
115
- const widgetHolder = {};
116
- const { lists: forLists = [] } = forContext;
117
- const currentIndex = forLists[0]?.currentIndex;
118
- const indexPostfix = (forContext.lists || [])
119
- .slice()
120
- .reverse()
121
- .map(({ currentIndex }) => ID_SEPARATOR + currentIndex)
122
- .join('');
123
-
124
- // traverse down the tree to set up all widgets
125
- dfsTree(
101
+ ctx,
126
102
  curForNode,
127
- (node, parentNode, cache) => {
128
- const parentForWidgetArr = ownerForWidgetHolder[node.id] || [];
129
- const { _waForKey } = node.value;
130
- const key = forContext.forItems?.[node.id]?.[_waForKey];
131
- let forExistingWidgetMap = {};
132
- let forExsitWidget;
133
-
134
- /**
135
- * for 起始节点,根据 existingWidgetMap 判断复用
136
- */
137
- if (node.id === curForNode.id) {
138
- if (existingWidgetMap[key] && existingWidgetMap[key].index === currentIndex) {
139
- forExistingWidgetMap = existingWidgetMap[key].widgets || {};
140
- forExsitWidget = forExistingWidgetMap[node.id];
141
- if (forExsitWidget) {
142
- cache[node.id] = {
143
- widgets: forExistingWidgetMap,
144
- };
145
- }
146
- }
147
- } else if (cache[parentNode?.id]) {
148
- forExsitWidget = cache[parentNode?.id].widgets[node.id] || null;
149
- if (forExsitWidget) {
150
- cache[node.id] = cache[parentNode?.id];
151
- }
152
- }
153
- const existedWidget = forExsitWidget || null;
103
+ dataBinds,
104
+ ownerMpInst,
105
+ forContext = {},
106
+ failedBinds = [],
107
+ parentWidget = { children: observable([]), _disposers: [] },
108
+ widgetHolder = {}
109
+ ) {
110
+ const { ownerForWidgetHolder = {}, existingWidgetMap = {} } = ctx;
111
+ /**
112
+ * 不能类似web实现记录额外的 _disposers
113
+ * const widgetHolder = { _disposers: [] }
114
+ * 因为 merger-render.initMergeRenderer 里面没有特殊处理
115
+ * 因为 构建 widgets 过程中对 $page.widgets 进行了访问,需要使用副作用的方式,保持 $page.widgets 引用
116
+ */
117
+ // const widgetHolder = {};
118
+ const { lists: forLists = [] } = forContext;
119
+ const currentIndex = forLists[0]?.currentIndex;
120
+ const indexPostfix = (forContext.lists || [])
121
+ .slice()
122
+ .reverse()
123
+ .map(({ currentIndex }) => ID_SEPARATOR + currentIndex)
124
+ .join('');
125
+
126
+ // traverse down the tree to set up all widgets
127
+ dfsTree(
128
+ curForNode,
129
+ (node, parentNode, cache) => {
130
+ const parentForWidgetArr = ownerForWidgetHolder[node.id] || [];
131
+ const { _waForKey } = node.value;
132
+ const key = forContext.forItems?.[node.id]?.[_waForKey];
133
+ let forExistingWidgetMap = {};
134
+ let forExsitWidget;
154
135
 
155
- if (node.forCount === curForNode.forCount) {
156
136
  /**
157
- * 同一层循环作用域内,当前节点与 curForNode(循环根节点)在同一级循环作用域中
158
- * 即没有再开辟新级别的 for 循环
159
- * Leaf node
137
+ * for 起始节点,根据 existingWidgetMap 判断复用
160
138
  */
161
- let w = existedWidget;
162
- if (!existedWidget) {
163
- const parentNode = node.parent;
164
- let parent = parentNode ? widgetHolder[parentNode.id] || ownerForWidgetHolder[parentNode.id] : null;
165
- w = createWidget(node.value, node.id, indexPostfix, parent, ownerMpInst, forContext.forItems?.[node.id]);
166
- w._key = key;
167
-
168
- if (!parent) {
169
- parentWidget.children.push(w);
139
+ if (node.id === curForNode.id) {
140
+ if (existingWidgetMap[key] && existingWidgetMap[key].index === currentIndex) {
141
+ forExistingWidgetMap = existingWidgetMap[key].widgets || {};
142
+ forExsitWidget = forExistingWidgetMap[node.id];
143
+ if (forExsitWidget) {
144
+ cache[node.id] = {
145
+ widgets: forExistingWidgetMap,
146
+ };
147
+ }
148
+ }
149
+ } else if (cache[parentNode?.id]) {
150
+ forExsitWidget = cache[parentNode?.id].widgets[node.id] || null;
151
+ if (forExsitWidget) {
152
+ cache[node.id] = cache[parentNode?.id];
170
153
  }
171
- } else {
172
- w.id = `${node.id}${indexPostfix}`;
173
- disposeWidget(existedWidget, true);
174
- }
175
- parentForWidgetArr.push?.(w);
176
- setUpWidgetDataBinds(w, dataBinds[node.id], forContext, failedBinds, ownerMpInst._getInstance());
177
- widgetHolder[node.id] = w;
178
- if (widgetHolder?.[node._ancestorId]) {
179
- // 在虚拟项 RepeaterItem 下挂载所有的子孙 __descendants
180
- // 这里不要用 lodashSet,否则会出现刷新几次,出现 Error: [mobx.array] Index out of bounds 的错误,原因暂不明
181
- widgetHolder[node._ancestorId]._descendants = widgetHolder[node._ancestorId]._descendants || {};
182
- widgetHolder[node._ancestorId]._descendants[node.id] = widgetHolder[node.id];
183
154
  }
184
- } else {
185
- if (!existedWidget) {
186
- widgetHolder[node.id] = observable([]);
155
+ const existedWidget = forExsitWidget || null;
156
+
157
+ if (node.forCount === curForNode.forCount) {
158
+ /**
159
+ * 同一层循环作用域内,当前节点与 curForNode(循环根节点)在同一级循环作用域中
160
+ * 即没有再开辟新级别的 for 循环
161
+ * Leaf node
162
+ */
163
+ let w = existedWidget;
164
+ if (!existedWidget) {
165
+ const parentNode = node.parent;
166
+ let parent = parentNode ? widgetHolder[parentNode.id] || ownerForWidgetHolder[parentNode.id] : null;
167
+ w = createWidget(node.value, node.id, indexPostfix, parent, ownerMpInst, forContext.forItems?.[node.id]);
168
+ w._key = key;
169
+
170
+ if (!parent) {
171
+ parentWidget.children.push(w);
172
+ }
173
+ } else {
174
+ w.id = `${node.id}${indexPostfix}`;
175
+ disposeWidget(existedWidget, true);
176
+ }
177
+ parentForWidgetArr.push?.(w);
178
+ setUpWidgetDataBinds(w, dataBinds[node.id], forContext, failedBinds, ownerMpInst._getInstance());
179
+ widgetHolder[node.id] = w;
180
+ if (widgetHolder?.[node._ancestorId]) {
181
+ // 在虚拟项 RepeaterItem 下挂载所有的子孙 __descendants
182
+ // 这里不要用 lodashSet,否则会出现刷新几次,出现 Error: [mobx.array] Index out of bounds 的错误,原因暂不明
183
+ widgetHolder[node._ancestorId]._descendants = widgetHolder[node._ancestorId]._descendants || {};
184
+ widgetHolder[node._ancestorId]._descendants[node.id] = widgetHolder[node.id];
185
+ }
187
186
  } else {
188
- // Reuse existed for widget array
189
- widgetHolder[node.id] = existedWidget;
187
+ if (!existedWidget) {
188
+ widgetHolder[node.id] = observable([]);
189
+ } else {
190
+ // Reuse existed for widget array
191
+ widgetHolder[node.id] = existedWidget;
192
+ }
193
+ if (parentForWidgetArr) {
194
+ parentForWidgetArr.push(widgetHolder[node.id]);
195
+ }
190
196
  }
191
- if (parentForWidgetArr) {
192
- parentForWidgetArr.push(widgetHolder[node.id]);
197
+ },
198
+ undefined,
199
+ );
200
+
201
+ // run for of next level
202
+ dfsTree(
203
+ curForNode,
204
+ (node) => {
205
+ if (node.forCount === curForNode.forCount + 1 && dataBinds[node.id] && dataBinds[node.id]._waFor) {
206
+ // find the node bound with next level for
207
+ const parent = getNodeParentWidget(node, widgetHolder, parentWidget);
208
+ const dispose = runFor(node, dataBinds, ownerMpInst, forContext, widgetHolder, failedBinds, parent);
209
+ parent._disposers.push(dispose); // Add the for bind dispose to the parent node of forNode
193
210
  }
194
- }
195
- },
196
- undefined,
197
- );
198
-
199
- // run for of next level
200
- dfsTree(
201
- curForNode,
202
- (node) => {
203
- if (node.forCount === curForNode.forCount + 1 && dataBinds[node.id] && dataBinds[node.id]._waFor) {
204
- // find the node bound with next level for
205
- const parent = getNodeParentWidget(node, widgetHolder, parentWidget);
206
- const dispose = runFor(node, dataBinds, ownerMpInst, forContext, widgetHolder, failedBinds, parent);
207
- parent._disposers.push(dispose); // Add the for bind dispose to the parent node of forNode
208
- }
209
- },
210
- undefined,
211
- );
211
+ },
212
+ undefined,
213
+ );
212
214
 
213
- retryFailedBinds(failedBinds);
215
+ retryFailedBinds(failedBinds);
214
216
 
215
- return { widgets: widgetHolder, rootWidget: widgetHolder[curForNode.id] || parentWidget };
217
+ return { widgets: widgetHolder, rootWidget: widgetHolder[curForNode.id] || parentWidget };
216
218
  }
217
219
 
218
220
  // Retry failed databinds
219
221
  function retryFailedBinds(failedBinds, finalTry) {
220
- const len = failedBinds.length;
221
- for (let i = 0; i < len; i++) {
222
- const setUpDataBind = failedBinds.shift();
223
- setUpDataBind(finalTry);
224
- }
222
+ const len = failedBinds.length;
223
+ for (let i = 0; i < len; i++) {
224
+ const setUpDataBind = failedBinds.shift();
225
+ setUpDataBind(finalTry);
226
+ }
225
227
  }
226
228
 
227
229
  /**
@@ -234,442 +236,458 @@ for (let i = 0; i < len; i++) {
234
236
  */
235
237
  const _FOR_ERROR_CACHE_MAP = {};
236
238
  function runFor(curForNode, dataBinds, ownerMpInst, forContext, ownerForWidgetHolder, failedBinds, parentWidget) {
237
- const nodeId = curForNode.id;
238
- const { _waForKey } = curForNode.value;
239
-
240
- const dispose = autorun(() => {
241
- let forList = [];
242
- try {
243
- clearTimeout(_FOR_ERROR_CACHE_MAP[nodeId]);
244
-
245
- const $instance = ownerMpInst._getInstance();
246
- const dataContext = untracked(() => generateDataContext(parentWidget));
247
- const $w = untracked(() => generateWidgetAPIContext($instance?.__internal__?.$w, parentWidget, forContext));
248
-
249
- forList = dataBinds[nodeId]._waFor.call(
250
- $instance,
251
- $instance,
252
- forContext.lists,
253
- forContext.forItems,
254
- undefined,
255
- dataContext,
256
- $w,
257
- );
258
- if (!Array.isArray(forList)) {
239
+ const nodeId = curForNode.id;
240
+ const { _waForKey } = curForNode.value;
241
+
242
+ const dispose = autorun(() => {
243
+ let forList = [];
244
+ try {
245
+ clearTimeout(_FOR_ERROR_CACHE_MAP[nodeId]);
246
+
247
+ const $instance = ownerMpInst._getInstance();
248
+ const dataContext = untracked(() => generateDataContext(parentWidget));
249
+ const $w = untracked(() => generateWidgetAPIContext($instance?.__internal__?.$w, parentWidget, forContext));
250
+
251
+ forList = dataBinds[nodeId]._waFor.call(
252
+ $instance,
253
+ $instance,
254
+ forContext.lists,
255
+ forContext.forItems,
256
+ undefined,
257
+ dataContext,
258
+ $w,
259
+ );
260
+ if (!Array.isArray(forList)) {
261
+ forList = [];
262
+ }
263
+ } catch (e) {
259
264
  forList = [];
265
+ _FOR_ERROR_CACHE_MAP[nodeId] = setTimeout(() => {
266
+ console.warn('For binding error', nodeId, e);
267
+ }, 1000);
260
268
  }
261
- } catch (e) {
262
- forList = [];
263
- _FOR_ERROR_CACHE_MAP[nodeId] = setTimeout(() => {
264
- console.warn('For binding error', nodeId, e);
265
- }, 1000);
266
- }
267
-
268
- // Track list change (e.g. push)
269
- forList.forEach((e) => {});
270
269
 
271
- untracked(() => {
272
- // dispose widgets before reused instead
273
- // disposeWidgets(parentForWidgets[curForNode.id])
274
- const exsitMap = forList.reduce((map, item, index) => {
275
- const cache = item?.[_waForKey];
276
- if (map[cache] === undefined) {
277
- map[cache] = index;
278
- }
279
- return map;
280
- }, {});
281
- const forWidgets = ownerForWidgetHolder[nodeId];
282
- const existingWidgetMap = {};
283
- const existingWidgetIndexMap = {};
284
- const extraWidgetsIndexMap = {};
285
- forWidgets.forEach((widget, index) => {
286
- if (exsitMap[widget._key] !== undefined) {
287
- const nodeId = widget.id?.split(ID_SEPARATOR)[0];
288
- existingWidgetMap[widget._key] = { index: exsitMap[widget._key], widgets: { [nodeId]: widget } };
289
- /**
290
- * 此处依赖了 existingWidgetMap[widget._key].widgets 的引用,
291
- * 为了直接可以通过 index 访问到 existingWidgetMap 里的值进行编辑
292
- * 但是依赖引用关系,存在维护风险
293
- */
294
- existingWidgetIndexMap[index] = existingWidgetMap[widget._key].widgets;
295
- // need to use uqique key
296
- exsitMap[widget._key] = undefined;
297
- } else {
298
- extraWidgetsIndexMap[index] = widget;
299
- }
300
- });
270
+ // Track list change (e.g. push)
271
+ forList.forEach((e) => {});
301
272
 
302
- // clean extra widgets of previous for run
303
- dfsTree(
304
- curForNode,
305
- (node) => {
306
- const arr = ownerForWidgetHolder[node.id] || [];
307
- /**
308
- * clone 上次 for 已有的 widgets
309
- */
310
- if (node.id !== curForNode.id) {
311
- arr.forEach((item, index) => {
312
- if (existingWidgetIndexMap[index]) {
313
- existingWidgetIndexMap[index][node.id] = item;
314
- }
315
- });
273
+ untracked(() => {
274
+ // dispose widgets before reused instead
275
+ // disposeWidgets(parentForWidgets[curForNode.id])
276
+ const exsitMap = forList.reduce((map, item, index) => {
277
+ const cache = item?.[_waForKey];
278
+ if (map[cache] === undefined) {
279
+ map[cache] = index;
316
280
  }
317
- /**
318
- * 重头开始生成
319
- * 清空原有 arr 并保持引用不变
320
- */
321
- arr.splice(0, arr.length);
322
- },
323
- undefined,
324
- );
325
-
326
- /**
327
- * 明确已经不会复用的节点,清除 mobx observer
328
- * 并递归清理子节点
329
- */
330
- for (const index in extraWidgetsIndexMap) {
331
- const w = extraWidgetsIndexMap[index];
332
- disposeWidget(w);
333
- const { children } = w.parent || parentWidget;
334
- children.remove(w);
335
- // w.parent = null
336
- }
281
+ return map;
282
+ }, {});
283
+ const forWidgets = ownerForWidgetHolder[nodeId];
284
+ const existingWidgetMap = {};
285
+ const existingWidgetIndexMap = {};
286
+ const extraWidgetsIndexMap = {};
287
+ forWidgets.forEach((widget, index) => {
288
+ if (exsitMap[widget._key] !== undefined) {
289
+ const nodeId = widget.id?.split(ID_SEPARATOR)[0];
290
+ existingWidgetMap[widget._key] = { index: exsitMap[widget._key], widgets: { [nodeId]: widget } };
291
+ /**
292
+ * 此处依赖了 existingWidgetMap[widget._key].widgets 的引用,
293
+ * 为了直接可以通过 index 访问到 existingWidgetMap 里的值进行编辑
294
+ * 但是依赖引用关系,存在维护风险
295
+ */
296
+ existingWidgetIndexMap[index] = existingWidgetMap[widget._key].widgets;
297
+ // need to use uqique key
298
+ exsitMap[widget._key] = undefined;
299
+ } else {
300
+ extraWidgetsIndexMap[index] = widget;
301
+ }
302
+ });
337
303
 
338
- const isInRepeaterChild = parentWidget?.widgetType === `${REPEATER.MODULE_NAME}:${REPEATER.REPEATER_NAME}`;
339
- forList.forEach((item, index) => {
340
- let forContextListAlias;
341
- let { lists = [], forItems = {} } = forContext;
342
- const listMeta = { currentItem: item, currentIndex: index };
343
- if (isInRepeaterChild) {
344
- forContextListAlias = {
345
- [`${parentWidget.forIndex}` || 'currentIndex']: listMeta.currentIndex,
346
- [`${parentWidget.forItem}` || 'currentItem']: listMeta.currentItem,
347
- };
348
- }
349
- const _forContext = {
350
- lists: [{ ...listMeta, alias: forContextListAlias }, ...lists],
351
- forItems: { ...forItems, [nodeId]: item },
352
- };
353
- const { rootWidget } = createSubWidgetTree(
354
- { ownerForWidgetHolder, existingWidgetMap },
304
+ // clean extra widgets of previous for run
305
+ dfsTree(
355
306
  curForNode,
356
- dataBinds,
357
- ownerMpInst,
358
- _forContext,
359
- failedBinds,
360
- parentWidget,
307
+ (node) => {
308
+ const arr = ownerForWidgetHolder[node.id] || [];
309
+ /**
310
+ * clone 上次 for 已有的 widgets
311
+ */
312
+ if (node.id !== curForNode.id) {
313
+ arr.forEach((item, index) => {
314
+ if (existingWidgetIndexMap[index]) {
315
+ existingWidgetIndexMap[index][node.id] = item;
316
+ }
317
+ });
318
+ }
319
+ /**
320
+ * 重头开始生成
321
+ * 清空原有 arr 并保持引用不变
322
+ */
323
+ arr.splice(0, arr.length);
324
+ },
325
+ undefined,
361
326
  );
362
- rootWidget._forContext = _forContext;
327
+
328
+ /**
329
+ * 明确已经不会复用的节点,清除 mobx observer
330
+ * 并递归清理子节点
331
+ */
332
+ for (const index in extraWidgetsIndexMap) {
333
+ const w = extraWidgetsIndexMap[index];
334
+ disposeWidget(w);
335
+ const { children } = w.parent || parentWidget;
336
+ children.remove(w);
337
+ // w.parent = null
338
+ }
339
+
340
+ const isInRepeaterChild = parentWidget?.widgetType === `${REPEATER.MODULE_NAME}:${REPEATER.REPEATER_NAME}`;
341
+ forList.forEach((item, index) => {
342
+ let forContextListAlias;
343
+ let { lists = [], forItems = {} } = forContext;
344
+ const listMeta = { currentItem: item, currentIndex: index };
345
+ if (isInRepeaterChild) {
346
+ forContextListAlias = {
347
+ [`${parentWidget.forIndex}` || 'currentIndex']: listMeta.currentIndex,
348
+ [`${parentWidget.forItem}` || 'currentItem']: listMeta.currentItem,
349
+ };
350
+ }
351
+ const _forContext = {
352
+ lists: [{ ...listMeta, alias: forContextListAlias }, ...lists],
353
+ forItems: { ...forItems, [nodeId]: item },
354
+ };
355
+ const { rootWidget } = createSubWidgetTree(
356
+ { ownerForWidgetHolder, existingWidgetMap },
357
+ curForNode,
358
+ dataBinds,
359
+ ownerMpInst,
360
+ _forContext,
361
+ failedBinds,
362
+ parentWidget,
363
+ );
364
+ rootWidget._forContext = _forContext;
365
+ });
363
366
  });
364
367
  });
365
- });
366
368
 
367
- return dispose;
369
+ return dispose;
368
370
  }
369
371
 
370
372
  function createWidget(props, nodeId, indexPostfix, parent, ownerMpInst, forContext) {
371
- const { widgetType, _parentId, ...restProps } = props;
372
- const w = observable(restProps);
373
- const id = `${nodeId}${indexPostfix}`;
374
-
375
- // Builtin props
376
- w.id = id; // 重用之后要修改id
377
- // Object.defineProperty(w, 'id', { value: id });
378
- Object.defineProperty(w, 'widgetType', { value: widgetType });
379
- Object.defineProperty(w, '_scope', {
380
- value: observable({
381
- id: nodeId,
382
- dataContext: {},
383
- /**
384
- * 当前节点的 for currentItem 对象
385
- */
386
- forContext,
387
- }),
388
- });
389
-
390
- // w._disposers = []
391
- // w.children = []
392
- Object.defineProperty(w, 'children', { value: observable([]) });
393
- Object.defineProperty(w, '_disposers', { value: observable([]) });
394
- Object.defineProperty(w, '_eventListeners', { value: new EventEmitter() });
395
- if (parent) {
396
- // w.parent = parent
397
- Object.defineProperty(w, 'parent', { value: parent });
398
- parent.children.push(w);
399
- }
373
+ const { widgetType, _parentId, ...restProps } = props;
374
+ const w = observable(restProps);
375
+ const id = `${nodeId}${indexPostfix}`;
376
+
377
+ // Builtin props
378
+ w.id = id; // 重用之后要修改id
379
+ // Object.defineProperty(w, 'id', { value: id });
380
+ Object.defineProperty(w, 'widgetType', { value: widgetType });
381
+ Object.defineProperty(w, '_scope', {
382
+ value: observable({
383
+ id: nodeId,
384
+ dataContext: {},
385
+ /**
386
+ * 当前节点的 for currentItem 对象
387
+ */
388
+ forContext,
389
+ }),
390
+ });
391
+
392
+ // w._disposers = []
393
+ // w.children = []
394
+ Object.defineProperty(w, 'children', { value: observable([]) });
395
+ Object.defineProperty(w, '_disposers', { value: observable([]) });
396
+ Object.defineProperty(w, '_eventListeners', { value: new EventEmitter() });
397
+ if (parent) {
398
+ // w.parent = parent
399
+ Object.defineProperty(w, 'parent', { value: parent });
400
+ parent.children.push(w);
401
+ }
400
402
 
401
- switch (widgetType) {
402
- case `${REPEATER.MODULE_NAME}:${REPEATER.REPEATER_NAME}`: {
403
- if (!w.items) {
404
- Object.defineProperty(w, 'items', {
405
- get() {
406
- return (w.children || []).map((item) => {
407
- const descendants = {};
408
- Object.keys(item?._descendants || {}).forEach((key) => {
409
- descendants[key] = item._descendants[key]._userWidget;
403
+ switch (widgetType) {
404
+ case `${REPEATER.MODULE_NAME}:${REPEATER.REPEATER_NAME}`: {
405
+ if (!w.items) {
406
+ Object.defineProperty(w, 'items', {
407
+ get() {
408
+ return (w.children || []).map((item) => {
409
+ const descendants = {};
410
+ Object.keys(item?._descendants || {}).forEach((key) => {
411
+ descendants[key] = item._descendants[key]._userWidget;
412
+ });
413
+ return descendants;
410
414
  });
411
- return descendants;
412
- });
413
- },
414
- });
415
+ },
416
+ });
417
+ }
418
+ break;
415
419
  }
416
- break;
417
420
  }
418
- }
419
421
 
420
- mountBuiltinWigetsAPI(w, ownerMpInst);
421
- return w;
422
+ mountBuiltinWigetsAPI(w, ownerMpInst);
423
+ return w;
422
424
  }
423
425
 
424
426
  function setUpWidgetDataBinds(w, dataBinds, forContext, failedBinds, ctx) {
425
- Object.keys(dataBinds || {})
426
- .sort((a, b) => {
427
- return a.length - b.length > 0 ? 1 : -1;
428
- })
429
- .map((prop) => {
430
- if (prop === '_waFor') {
431
- return;
432
- }
433
- let timer = null;
434
- const setUpDataBind = (isFinalTry) => {
435
- let ran = false;
436
- const dispose = autorun((reaction) => {
437
- try {
438
- clearTimeout(timer);
439
-
440
- const dataContext = untracked(() => generateDataContext(w));
441
- const $w = untracked(() => generateWidgetAPIContext(ctx?.__internal__?.$w, w, forContext));
442
-
443
- // Computed data bind in the next tick since data bind may read widgets data
444
- const value = dataBinds[prop].call(
445
- ctx,
446
- ctx,
447
- forContext.lists,
448
- forContext.forItems,
449
- undefined,
450
- dataContext,
451
- $w,
452
- );
453
- const paths = prop.split('.').filter((key) => !!key);
454
- if (paths.length > 1) {
455
- // 一定要 untracked 不然爆栈了
456
- untracked(() => lodashSet(w, prop, value));
457
- } else {
458
- // 普通 key 直接赋值
459
- w[prop] = value;
460
- }
461
- } catch (e) {
462
- if (prop === '_waIf') {
463
- w[prop] = false;
464
- }
427
+ Object.keys(dataBinds || {})
428
+ .sort((a, b) => {
429
+ return a.length - b.length > 0 ? 1 : -1;
430
+ })
431
+ .map((prop) => {
432
+ if (prop === '_waFor') {
433
+ return;
434
+ }
435
+ let timer = null;
436
+ const setUpDataBind = (isFinalTry) => {
437
+ let ran = false;
438
+ const dispose = autorun((reaction) => {
439
+ try {
440
+ clearTimeout(timer);
441
+
442
+ const dataContext = untracked(() => generateDataContext(w));
443
+ const $w = untracked(() => generateWidgetAPIContext(ctx?.__internal__?.$w, w, forContext));
444
+
445
+ // Computed data bind in the next tick since data bind may read widgets data
446
+ const value = dataBinds[prop].call(
447
+ ctx,
448
+ ctx,
449
+ forContext.lists,
450
+ forContext.forItems,
451
+ undefined,
452
+ dataContext,
453
+ $w,
454
+ );
455
+ const paths = prop.split('.').filter((key) => !!key);
456
+ if (paths.length > 1) {
457
+ // 一定要 untracked 不然爆栈了
458
+ untracked(() => lodashSet(w, prop, value));
459
+ } else {
460
+ // 普通 key 直接赋值
461
+ w[prop] = value;
462
+ }
463
+ } catch (e) {
464
+ if (prop === '_waIf') {
465
+ w[prop] = false;
466
+ }
465
467
 
466
- if (isFinalTry || ran) {
467
- timer = setTimeout(() => {
468
- console.warn(`Error computing data bind ${w.id}.${prop}`, e);
469
- }, 1000);
470
- } else {
471
- failedBinds.push((...args) => {
472
- reaction.dispose();
473
- return setUpDataBind(...args);
474
- });
475
- }
468
+ if (isFinalTry || ran) {
469
+ timer = setTimeout(() => {
470
+ console.warn(`Error computing data bind ${w.id}.${prop}`, e);
471
+ }, 1000);
472
+ } else {
473
+ failedBinds.push((...args) => {
474
+ reaction.dispose();
475
+ return setUpDataBind(...args);
476
+ });
477
+ }
476
478
 
477
- ran = true;
478
- }
479
- });
480
- w._disposers.push(dispose);
481
- };
482
- setUpDataBind();
483
- });
479
+ ran = true;
480
+ }
481
+ });
482
+ w._disposers.push(dispose);
483
+ };
484
+ setUpDataBind();
485
+ });
484
486
  }
485
487
 
486
488
  export function generateForContextOfWidget(widget) {
487
- const forContext = widget._forContext;
488
- if (forContext) return forContext;
489
- if (widget.parent) return generateForContextOfWidget(widget.parent);
489
+ const forContext = widget._forContext;
490
+ if (forContext) return forContext;
491
+ if (widget.parent) return generateForContextOfWidget(widget.parent);
490
492
  }
491
493
 
492
494
  export const ID_SEPARATOR = '-';
493
495
  export function getWidget(widgets, id) {
494
- return getDeep(widgets, id, ID_SEPARATOR);
496
+ return getDeep(widgets, id, ID_SEPARATOR);
495
497
  }
496
498
 
497
499
  function getNodeParentWidget(node, widgets, defaultParent = { children: observable([]), _disposers: [] }) {
498
- return (node?.parent?.id && widgets?.[node.parent.id]) || defaultParent;
500
+ return (node?.parent?.id && widgets?.[node.parent.id]) || defaultParent;
499
501
  }
500
502
 
501
503
  /**
502
504
  * Add parent, children to widget
503
505
  */
504
506
  function createWidgetDataTree(widgets, dataBinds) {
505
- const virtualRoot = { children: [], forCount: 0 };
506
- const nodes = Object.keys(widgets).reduce((result, id) => {
507
- const w = widgets[id];
508
- result[id] = { id, value: w, _order: w._order, children: [], parent: null, forCount: 0 };
509
- return result;
510
- }, {});
511
-
512
- // Create widgets tree API
513
- Object.keys(nodes).map((id) => {
514
- const curNode = nodes[id];
515
- const parent = nodes[widgets[id]._parentId];
516
- // delete widgets[id]._parentId
517
- if (!parent) {
518
- virtualRoot.children.push(curNode);
519
- return;
520
- }
521
- curNode.parent = parent;
522
- parent.children.push(curNode);
523
- });
524
-
525
- // Sort children
526
- Object.keys(nodes).map((id) => {
527
- nodes[id].children.sort((a, b) => a._order - b._order);
528
- });
529
-
530
- virtualRoot.children.map(addForCount);
531
-
532
- // dfs, add forCount
533
- function addForCount(node) {
534
- if (node.parent) {
535
- node.forCount = node.parent.forCount;
536
- const { widgetType } = node.parent.value;
537
- if (widgetType === `${REPEATER.MODULE_NAME}:${REPEATER.REPEATER_ITEM_NAME}`) {
538
- node._ancestorId = node.parent.id;
507
+ const virtualRoot = { children: [], forCount: 0 };
508
+ const nodes = Object.keys(widgets).reduce((result, id) => {
509
+ const w = widgets[id];
510
+ result[id] = { id, value: w, _order: w._order, children: [], parent: null, forCount: 0 };
511
+ return result;
512
+ }, {});
513
+
514
+ // Create widgets tree API
515
+ Object.keys(nodes).map((id) => {
516
+ const curNode = nodes[id];
517
+ const parent = nodes[widgets[id]._parentId];
518
+ // delete widgets[id]._parentId
519
+ if (!parent) {
520
+ virtualRoot.children.push(curNode);
521
+ return;
539
522
  }
540
- if (node.parent?._ancestorId) {
541
- // Repeater 作用域内的所有子孙(排除里面的 Repeater 组件,它本身又产生深一层的作用域)继承父级的循环信息
542
- if (!node._ancestorId) {
543
- node._ancestorId = node.parent._ancestorId;
523
+ curNode.parent = parent;
524
+ parent.children.push(curNode);
525
+ });
526
+
527
+ // Sort children
528
+ Object.keys(nodes).map((id) => {
529
+ nodes[id].children.sort((a, b) => a._order - b._order);
530
+ });
531
+
532
+ virtualRoot.children.map(addForCount);
533
+
534
+ // dfs, add forCount
535
+ function addForCount(node) {
536
+ if (node.parent) {
537
+ node.forCount = node.parent.forCount;
538
+ const { widgetType } = node.parent.value;
539
+ if (widgetType === `${REPEATER.MODULE_NAME}:${REPEATER.REPEATER_ITEM_NAME}`) {
540
+ node._ancestorId = node.parent.id;
541
+ }
542
+ if (node.parent?._ancestorId) {
543
+ // Repeater 作用域内的所有子孙(排除里面的 Repeater 组件,它本身又产生深一层的作用域)继承父级的循环信息
544
+ if (!node._ancestorId) {
545
+ node._ancestorId = node.parent._ancestorId;
546
+ }
544
547
  }
545
548
  }
549
+ if (dataBinds[node.id]?._waFor) {
550
+ node.forCount += 1;
551
+ }
552
+ node.children.map(addForCount);
546
553
  }
547
- if (dataBinds[node.id]?._waFor) {
548
- node.forCount += 1;
549
- }
550
- node.children.map(addForCount);
551
- }
552
554
 
553
- return virtualRoot;
555
+ return virtualRoot;
554
556
  }
555
557
 
556
558
  function dfsTree(node, fn, parent, cache = {}) {
557
- node.value && fn(node, parent, cache);
558
- node.children.map((e) => dfsTree(e, fn, node.value ? node : null, cache));
559
+ node.value && fn(node, parent, cache);
560
+ node.children.map((e) => dfsTree(e, fn, node.value ? node : null, cache));
559
561
  }
560
562
 
561
563
  // dispose autorun, widget can be the virtual root widget
562
564
  export function disposeWidget(widget, noRecursive = false) {
563
- const disposers = widget._disposers;
564
- disposers.map((dispose) => dispose());
565
- disposers.splice(0, disposers.length);
566
- !noRecursive && widget.children.forEach((w) => disposeWidget(w));
565
+ const disposers = widget._disposers;
566
+ disposers.map((dispose) => dispose());
567
+ disposers.splice(0, disposers.length);
568
+ !noRecursive && widget.children.forEach((w) => disposeWidget(w));
567
569
  }
568
570
 
569
571
  export function createInitData(widgets, dataBinds, keyPrefix = '') {
570
- return Object.keys(widgets).reduce((result, id) => {
571
- if (!isWidgetInFor(id, widgets, dataBinds)) {
572
- result[keyPrefix + id] = resolveWidgetData(widgets[id]);
573
- } else {
574
- result[keyPrefix + id] = [];
575
- }
576
- return result;
577
- }, {});
572
+ return Object.keys(widgets).reduce((result, id) => {
573
+ if (!isWidgetInFor(id, widgets, dataBinds)) {
574
+ result[keyPrefix + id] = resolveWidgetData(widgets[id]);
575
+ } else {
576
+ result[keyPrefix + id] = [];
577
+ }
578
+ return result;
579
+ }, {});
578
580
  }
579
581
 
580
582
  function isWidgetInFor(id, widgets, dataBinds) {
581
- let curNode = widgets[id];
582
- let nodeId = id;
583
- while (curNode) {
584
- if (dataBinds[nodeId]?._waFor) {
585
- return true;
583
+ let curNode = widgets[id];
584
+ let nodeId = id;
585
+ while (curNode) {
586
+ if (dataBinds[nodeId]?._waFor) {
587
+ return true;
588
+ }
589
+ nodeId = curNode._parentId;
590
+ curNode = widgets[nodeId];
586
591
  }
587
- nodeId = curNode._parentId;
588
- curNode = widgets[nodeId];
589
- }
590
592
  }
591
593
 
592
594
  function mountBuiltinWigetsAPI(widget, owner) {
593
- // #1 builtin APIs
594
- widget.findWidgets = function (filter, includeInvisibleDescendants) {
595
- let { children = [] } = this;
596
- if (!includeInvisibleDescendants) {
597
- // include visible widgets only by default
598
- children = children.filter((e) => e._waIf !== false);
599
- }
600
- const matched = [];
601
- children.forEach((w) => {
602
- if (filter(w)) {
603
- matched.push(w);
595
+ // #1 builtin APIs
596
+ widget.findWidgets = function (filter, includeInvisibleDescendants) {
597
+ let { children = [] } = this;
598
+ if (!includeInvisibleDescendants) {
599
+ // include visible widgets only by default
600
+ children = children.filter((e) => e._waIf !== false);
604
601
  }
605
- matched.push(...w.findWidgets(filter, includeInvisibleDescendants));
606
- });
607
- return matched;
608
- };
602
+ const matched = [];
603
+ children.forEach((w) => {
604
+ if (filter(w)) {
605
+ matched.push(w);
606
+ }
607
+ matched.push(...w.findWidgets(filter, includeInvisibleDescendants));
608
+ });
609
+ return matched;
610
+ };
609
611
 
610
- widget.getWidgetsByType = function (type, includeInvisibleDescendants) {
611
- return this.findWidgets((w) => w.widgetType === type, includeInvisibleDescendants);
612
- };
612
+ widget.getWidgetsByType = function (type, includeInvisibleDescendants) {
613
+ return this.findWidgets((w) => w.widgetType === type, includeInvisibleDescendants);
614
+ };
613
615
 
614
- /**
615
- * Similar to selectOwnerComponent of WX MP: https://developers.weixin.qq.com/miniprogram/dev/reference/api/Component.html
616
- */
617
- widget.getOwnerWidget = function () {
618
- return owner?._getInstance?.()?.node;
619
- };
620
-
621
- // Will be overwritten by composited component
622
- widget.getDom = function (fields) {
623
- return new Promise((resolve, reject) => {
624
- const query = (owner || wx).createSelectorQuery();
625
- query
626
- .select(`#${this.id}`)
627
- .fields(fields, (res) => {
628
- resolve(res);
629
- })
630
- .exec();
631
- });
632
- };
616
+ /**
617
+ * Similar to selectOwnerComponent of WX MP: https://developers.weixin.qq.com/miniprogram/dev/reference/api/Component.html
618
+ */
619
+ widget.getOwnerWidget = function () {
620
+ return owner?._getInstance?.()?.node;
621
+ };
633
622
 
634
- widget.on = function (type, listener) {
635
- this._eventListeners.on(type, listener);
636
- };
623
+ // Will be overwritten by composited component
624
+ widget.getDom = function (fields) {
625
+ return new Promise((resolve, reject) => {
626
+ const query = (owner || wx).createSelectorQuery();
627
+ query
628
+ .select(`#${this.id}`)
629
+ .fields(fields, (res) => {
630
+ resolve(res);
631
+ })
632
+ .exec();
633
+ });
634
+ };
637
635
 
638
- widget.off = function (type, listener) {
639
- this._eventListeners.off(type, listener);
640
- };
636
+ widget.on = function (type, listener) {
637
+ this._eventListeners.on(type, listener);
638
+ };
641
639
 
642
- widget.getConfig = () => ({});
640
+ widget.off = function (type, listener) {
641
+ this._eventListeners.off(type, listener);
642
+ };
643
643
 
644
- const lowcode = compLowcodes[widget.widgetType];
645
- if (lowcode) {
646
- const { config } = lowcode;
647
- widget.getConfig = () => config;
648
- }
644
+ widget.getConfig = () => ({});
649
645
 
650
- widget._getInstanceRef = () => null;
646
+ const lowcode = compLowcodes[widget.widgetType];
647
+ if (lowcode) {
648
+ const { config } = lowcode;
649
+ widget.getConfig = () => config;
650
+ }
651
651
 
652
- /**
653
- * @deprecated
654
- */
655
- widget._methods = {};
652
+ switch (widget.widgetType) {
653
+ case `${REPEATER.MODULE_NAME}:${REPEATER.REPEATER_NAME}`: {
654
+ const currentRef = observable({ current: undefined });
655
+ widget._getInstanceRef = () => {
656
+ return currentRef;
657
+ }; // 默认初始值
658
+ widget._disposers.push(
659
+ autorun((r) => {
660
+ currentRef.current = { data: widget.data };
661
+ }),
662
+ );
663
+ break;
664
+ }
665
+ default: {
666
+ widget._getInstanceRef = () => null;
667
+ }
668
+ }
669
+
670
+ /**
671
+ * @deprecated
672
+ */
673
+ widget._methods = {};
656
674
 
657
- Object.defineProperty(widget, '_userWidget', {
658
- value: untracked(() => {
659
- return new UserWidget(widget);
660
- }),
661
- });
675
+ Object.defineProperty(widget, '_userWidget', {
676
+ value: untracked(() => {
677
+ return new UserWidget(widget);
678
+ }),
679
+ });
662
680
  }
663
681
 
664
682
  /**
665
683
  * 对外(用户)的 Widget
666
684
  */
667
685
  class UserWidget {
668
- _widget = null;
686
+ _widget = null;
669
687
 
670
- get description() {
671
- const { id } = this._widget;
672
- return `
688
+ get description() {
689
+ const { id } = this._widget;
690
+ return `
673
691
  使用说明:
674
692
  1. sys 命名空间下为内置方法,可通过 $w.${id}.sys.<成员> 或 $w.${id}.<成员> 访问。
675
693
  访问 id 示例: $w.${id}.id 或 $w.${id}.sys.id
@@ -678,127 +696,127 @@ get description() {
678
696
  3. 通过 $w.${id}.<成员> 访问时,如果自定义成员与内置成员重名,则自定义成员覆盖内置成员。
679
697
  4. [注意]: 请不要直接访问 _widget,它里面的成员为内部实现,随时可能进行调整
680
698
  `;
681
- }
699
+ }
682
700
 
683
- constructor(widget) {
684
- this._widget = widget;
685
- return new Proxy(this, {
686
- get(target, prop) {
687
- if (prop in target) {
688
- return target[prop];
689
- }
701
+ constructor(widget) {
702
+ this._widget = widget;
703
+ return new Proxy(this, {
704
+ get(target, prop) {
705
+ if (prop in target) {
706
+ return target[prop];
707
+ }
690
708
 
691
- // 优先 custom
692
- if (target.custom[prop]) {
693
- return target.custom[prop];
694
- }
709
+ // 优先 custom
710
+ if (target.custom[prop]) {
711
+ return target.custom[prop];
712
+ }
695
713
 
696
- // 再尝试内置的方法和属性
697
- const buildinMember = target.sys[prop];
698
- if (buildinMember) return buildinMember;
714
+ // 再尝试内置的方法和属性
715
+ const buildinMember = target.sys[prop];
716
+ if (buildinMember) return buildinMember;
699
717
 
700
- // 兼容原来的 widget。最后直接代理到 widget 上,主要是访问组件的属性
701
- // return target._widget[prop];
702
- return undefined
703
- },
704
- });
705
- }
718
+ // 兼容原来的 widget。最后直接代理到 widget 上,主要是访问组件的属性
719
+ // return target._widget[prop];
720
+ return undefined;
721
+ },
722
+ });
723
+ }
706
724
 
707
- // 内置属性和方法命名空间
708
- get sys() {
709
- const widget = this._widget;
710
- const [module, component] = widget.widgetType?.split?.(':') || [];
711
- return {
712
- /**
713
- * 内置属性
714
- */
715
-
716
- get id() {
717
- return widget.id;
718
- },
725
+ // 内置属性和方法命名空间
726
+ get sys() {
727
+ const widget = this._widget;
728
+ const [module, component] = widget.widgetType?.split?.(':') || [];
729
+ return {
730
+ /**
731
+ * 内置属性
732
+ */
719
733
 
720
- get module() {
721
- return module;
722
- },
734
+ get id() {
735
+ return widget.id;
736
+ },
723
737
 
724
- get component() {
725
- return component;
726
- },
738
+ get module() {
739
+ return module;
740
+ },
727
741
 
728
- get name() {
729
- return widget.widgetType;
730
- },
742
+ get component() {
743
+ return component;
744
+ },
731
745
 
732
- get parent() {
733
- return widget.parent?._userWidget;
734
- },
746
+ get name() {
747
+ return widget.widgetType;
748
+ },
735
749
 
736
- get children() {
737
- return widget.children?.map((item) => item._userWidget) || [];
738
- },
750
+ get parent() {
751
+ return widget.parent?._userWidget;
752
+ },
739
753
 
740
- /**
741
- * 内置方法
742
- */
754
+ get children() {
755
+ return widget.children?.map((item) => item._userWidget) || [];
756
+ },
743
757
 
744
- closest(filter) {
745
- let { parent } = this;
746
- if (!filter) return parent;
758
+ /**
759
+ * 内置方法
760
+ */
747
761
 
748
- while (parent) {
749
- const matched = filter(parent);
750
- if (matched) return parent;
762
+ closest(filter) {
763
+ let { parent } = this;
764
+ if (!filter) return parent;
751
765
 
752
- parent = parent.parent;
753
- }
766
+ while (parent) {
767
+ const matched = filter(parent);
768
+ if (matched) return parent;
754
769
 
755
- return null;
756
- }
757
- };
758
- }
770
+ parent = parent.parent;
771
+ }
759
772
 
760
- get custom() {
761
- const { methods = {}, ...restInstance } = this._widget._getInstanceRef?.()?.current || {};
773
+ return null;
774
+ },
775
+ };
776
+ }
762
777
 
763
- const userCustomMember = {
764
- ...this._widget._methods,
765
- ...restInstance,
766
- ...methods,
767
- };
778
+ get custom() {
779
+ const { methods = {}, ...restInstance } = this._widget._getInstanceRef?.()?.current || {};
768
780
 
769
- return userCustomMember;
770
- }
781
+ const userCustomMember = {
782
+ ...this._widget._methods,
783
+ ...restInstance,
784
+ ...methods,
785
+ };
786
+
787
+ return userCustomMember;
788
+ }
771
789
  }
772
790
 
773
791
  export function generateWidgetAPIContext($w = {}, widget, forContext) {
774
- return new Proxy($w, {
775
- get(target, prop) {
776
- // debugger;
777
-
778
- /**
779
- * for context 变量优先
780
- */
781
- const { lists = [] } = forContext;
782
- for (const meta of lists) {
783
- const map = meta.alias || {};
784
- if (prop in map) {
785
- return map[prop];
792
+ return new Proxy($w, {
793
+ get(target, prop) {
794
+ // debugger;
795
+
796
+ /**
797
+ * for context 变量优先
798
+ */
799
+ const { lists = [] } = forContext;
800
+ for (const meta of lists) {
801
+ const map = meta.alias || {};
802
+ if (prop in map) {
803
+ return map[prop];
804
+ }
786
805
  }
787
- }
788
806
 
789
- // 尝试代理同级 widget
790
- if (widget) {
791
- let { parent } = widget;
792
- while (parent) {
793
- if (parent._descendants?.[prop]) {
794
- return parent._descendants[prop]._userWidget;
807
+ // 尝试代理同级 widget
808
+ if (widget) {
809
+ let { parent } = widget;
810
+ while (parent) {
811
+ if (parent._descendants?.[prop]) {
812
+ return parent._descendants[prop]._userWidget;
813
+ }
814
+ parent = parent.parent;
795
815
  }
796
- parent = parent.parent;
797
816
  }
798
- }
799
817
 
800
- // 尝试代理到全局的 $w
801
- return target[prop];
802
- },
803
- });
818
+ // 尝试代理到全局的 $w
819
+ return target[prop];
820
+ },
821
+ });
804
822
  }