@cloudbase/lowcode-builder 1.3.9 → 1.3.10

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