@cloudbase/framework-plugin-low-code 0.7.32 → 0.7.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/builder/mp/util.d.ts.map +1 -1
- package/lib/builder/mp/util.js +4 -0
- package/lib/builder/mp/wxml.d.ts.map +1 -1
- package/lib/builder/mp/wxml.js +8 -18
- package/lib/builder/service/builder/generate.d.ts.map +1 -1
- package/lib/builder/service/builder/generate.js +12 -23
- package/lib/weapps-core/types/app.d.ts +1 -0
- package/lib/weapps-core/types/app.d.ts.map +1 -1
- package/lib/weapps-core/utils/file.d.ts +1 -1
- package/lib/weapps-core/utils/formily.d.ts.map +1 -1
- package/lib/weapps-core/utils/formily.js +12 -3
- package/package.json +2 -2
- package/template/html/index.html.ejs +1 -1
- package/template/mp/common/util.js +1 -0
- package/template/mp/common/widget.js +375 -209
- package/template/mp/component/index.js +1 -1
- package/template/mp/page/index.js +1 -1
- package/template/src/handlers/FieldMiddleware/renderer.jsx +6 -3
- package/template/src/handlers/render.jsx +16 -4
- package/template/src/handlers/utils/widgets.js +127 -55
- package/template/src/index.jsx +3 -1
- package/template/src/pages/composite.tpl +17 -11
|
@@ -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 = [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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(
|
|
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(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
|
56
|
-
const
|
|
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) {
|
|
59
|
-
|
|
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
|
-
|
|
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(
|
|
91
|
-
|
|
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
|
-
|
|
114
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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 = {}
|
|
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(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
|
192
|
-
Object.keys(dataBinds || {})
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
//
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
|
|
213
|
-
|
|
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]
|
|
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]
|
|
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) {
|
|
326
|
-
|
|
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
|
|
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
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
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
|
}
|