@cloudbase/framework-plugin-low-code 0.6.17 → 0.6.19

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/index.js CHANGED
@@ -292,7 +292,7 @@ class LowCodePlugin extends framework_core_1.Plugin {
292
292
  return __awaiter(this, void 0, void 0, function* () { });
293
293
  }
294
294
  build() {
295
- var _a;
295
+ var _a, _b, _c, _d;
296
296
  return __awaiter(this, void 0, void 0, function* () {
297
297
  let { logger } = this.api;
298
298
  const staticDir = path_1.default.resolve(__dirname, '../../../static');
@@ -326,13 +326,53 @@ class LowCodePlugin extends framework_core_1.Plugin {
326
326
  this.api.logger.error('获取静态托管失败: ', e);
327
327
  throw e;
328
328
  }
329
+ const domain = ((_b = this._website) === null || _b === void 0 ? void 0 : _b.cdnDomain) || ((_c = mainAppSerializeData.extra) === null || _c === void 0 ? void 0 : _c.domain);
330
+ if (common_2.buildAsWebByBuildType(buildTypeList) &&
331
+ this._resolvedInputs.deployOptions.mode === types_1.DEPLOY_MODE.UPLOAD) {
332
+ let { appConfig = {} } = mainAppSerializeData;
333
+ let { window = {} } = appConfig;
334
+ try {
335
+ const { Data = {} } = yield this.api.cloudbaseManager
336
+ .commonService('lowcode', '2021-01-08')
337
+ .call({
338
+ Action: 'DescribeAppCustomUrls',
339
+ Param: {
340
+ EnvId: this.api.envId,
341
+ IgnorePublished: true,
342
+ WeAppId: appId,
343
+ },
344
+ });
345
+ this.api.logger.debug('DescribeAppCustomUrls', Data, {
346
+ EnvId: this.api.envId,
347
+ IgnorePublished: true,
348
+ WeAppId: appId,
349
+ });
350
+ this._gatewayConfig = (_d = Data === null || Data === void 0 ? void 0 : Data.Items) === null || _d === void 0 ? void 0 : _d[0];
351
+ if (this._gatewayConfig) {
352
+ const path = this._gatewayConfig.Path;
353
+ window.publicPath = `https://${domain}${this._getWebRootPath()}`;
354
+ if (!common_2.buildAsAdminPortalByBuildType(buildTypeList)) {
355
+ window.basename = path;
356
+ }
357
+ appConfig.window = window;
358
+ this._resolvedInputs.mainAppSerializeData.appConfig = appConfig;
359
+ }
360
+ }
361
+ catch (e) {
362
+ this.api.logger.error('路由失败', e, {
363
+ EnvId: this.api.envId,
364
+ IgnorePublished: true,
365
+ WeAppId: appId,
366
+ });
367
+ }
368
+ }
329
369
  try {
330
370
  if (!debug) {
331
371
  pauseConsoleOutput();
332
372
  }
333
373
  this._time("build process");
334
374
  this._appPath = yield new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
335
- var _b, _c, _d, _e;
375
+ var _e, _f;
336
376
  try {
337
377
  yield core_1.default({
338
378
  mainAppSerializeData,
@@ -345,16 +385,16 @@ class LowCodePlugin extends framework_core_1.Plugin {
345
385
  runtime: this._resolvedInputs.runtime,
346
386
  ignoreInstall: this._resolvedInputs.ignoreInstall,
347
387
  mode: webpackMode,
348
- deployMode: (_b = this._resolvedInputs.deployOptions) === null || _b === void 0 ? void 0 : _b.mode,
388
+ deployMode: (_e = this._resolvedInputs.deployOptions) === null || _e === void 0 ? void 0 : _e.mode,
349
389
  watch: false,
350
390
  generateMpType,
351
391
  generateMpPath,
352
392
  isCleanDistDir: false,
353
393
  plugins,
354
394
  extraData,
355
- isCrossAccount: this._resolvedInputs.mpAppId !== ((_c = this._resolvedInputs.deployOptions) === null || _c === void 0 ? void 0 : _c.targetMpAppId),
395
+ isCrossAccount: this._resolvedInputs.mpAppId !== ((_f = this._resolvedInputs.deployOptions) === null || _f === void 0 ? void 0 : _f.targetMpAppId),
356
396
  resourceAppid: this._resolvedInputs.mpAppId,
357
- domain: ((_d = this._website) === null || _d === void 0 ? void 0 : _d.cdnDomain) || ((_e = mainAppSerializeData.extra) === null || _e === void 0 ? void 0 : _e.domain),
397
+ domain,
358
398
  }, (err, result) => __awaiter(this, void 0, void 0, function* () {
359
399
  if (!err) {
360
400
  try {
@@ -556,8 +596,10 @@ class LowCodePlugin extends framework_core_1.Plugin {
556
596
  const isPreview = (deployOptions === null || deployOptions === void 0 ? void 0 : deployOptions.mode) === types_1.DEPLOY_MODE.PREVIEW;
557
597
  const link = common_2.buildAsAdminPortalByBuildType(this._resolvedInputs.buildTypeList)
558
598
  ? `https://${this._website.cdnDomain}/adminportal/#/app/${isPreview ? `${appId}-preview` : appId}?envType=${isPreview ? 'preivew' : 'prod'}`
559
- : `https://${this._website.cdnDomain +
560
- this._webPlugin.resolvedInputs.cloudPath}`;
599
+ : this._gatewayConfig
600
+ ? `https://${this._gatewayConfig.Domain + this._gatewayConfig.Path}`
601
+ : `https://${this._website.cdnDomain +
602
+ this._webPlugin.resolvedInputs.cloudPath}`;
561
603
  const qrcodeOutputPath = path_1.default.resolve(this.api.projectPath, QRCODE_PATH);
562
604
  yield qrcode_1.default.toFile(path_1.default.resolve(this.api.projectPath, QRCODE_PATH), link, {
563
605
  errorCorrectionLevel: 'M',
@@ -916,12 +958,14 @@ class LowCodePlugin extends framework_core_1.Plugin {
916
958
  }
917
959
  return arr;
918
960
  }, []);
919
- (_b = this._resolvedInputs.mainAppSerializeData.pageInstanceList) === null || _b === void 0 ? void 0 : _b.forEach((page) => {
920
- rules.push({
921
- keyPrefixEquals: `${path.slice(1)}${page.id}`,
922
- replaceKeyWith: path,
961
+ if (!this._gatewayConfig) {
962
+ (_b = this._resolvedInputs.mainAppSerializeData.pageInstanceList) === null || _b === void 0 ? void 0 : _b.forEach((page) => {
963
+ rules.push({
964
+ keyPrefixEquals: `${path.slice(1)}${page.id}`,
965
+ replaceKeyWith: path,
966
+ });
923
967
  });
924
- });
968
+ }
925
969
  this._rules = rules;
926
970
  }
927
971
  }
@@ -936,6 +980,18 @@ class LowCodePlugin extends framework_core_1.Plugin {
936
980
  domainConfig: { FollowRedirect: 'on' },
937
981
  }));
938
982
  yield Promise.all(modifyDomainConfigPromises);
983
+ if (this._gatewayConfig) {
984
+ yield this.api.cloudbaseManager
985
+ .commonService('lowcode', '2021-01-08')
986
+ .call({
987
+ Action: 'PublishAppCustomUrl',
988
+ Param: {
989
+ EnvId: this.api.envId,
990
+ WeAppId: this._resolvedInputs.appId,
991
+ IndexPath: this._getWebRootPath(),
992
+ },
993
+ });
994
+ }
939
995
  yield hostingService.setWebsiteDocument({
940
996
  indexDocument: 'index.html',
941
997
  routingRules: this._rules,
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.receiveDataByLowcodeDiff = exports.evalExpression = void 0;
4
4
  function evalExpression(code, runtime) {
5
5
  try {
6
- return runtime.eval(`(function(forItems){const $for = forItems; return ${code};})`);
6
+ return runtime.eval(`(function(forItems, $context){const $for = forItems; return ${code};})`);
7
7
  }
8
8
  catch (e) {
9
9
  runtime.console.error(`Error in expression:\t${code}\n\n`, e);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/framework-plugin-low-code",
3
- "version": "0.6.17",
3
+ "version": "0.6.19",
4
4
  "description": "云开发 Tencent CloudBase Framework Low Code Plugin,将低码配置生成完整项目并一键部署云开发资源。",
5
5
  "author": "yhsunshining@gmail.com",
6
6
  "homepage": "https://github.com/TencentCloudBase/cloudbase-framework#readme",
@@ -24,6 +24,8 @@ export const CompRenderer = observer(function (props) {
24
24
  genericComp = {},
25
25
  emitEvents = [],
26
26
  componentSchema = {},
27
+ context = {},
28
+ updateContext,
27
29
  } = props;
28
30
 
29
31
  const [blockIndex, setBlockIndex] = useState();
@@ -63,6 +65,14 @@ export const CompRenderer = observer(function (props) {
63
65
  // 组件最终用于执行的事件函数
64
66
  const emit = useCallback(
65
67
  (trigger, eventData, forItems, domEvent, scopeContext) => {
68
+ // 如果是数据容器,则将传过来的data,赋值给容器上下文context
69
+ if (
70
+ trigger === 'onDataChange' &&
71
+ componentSchema?.compConfig?.isDataContainer
72
+ ) {
73
+ updateContext(compId, eventData?.data);
74
+ }
75
+
66
76
  const listeners = listenerInstances;
67
77
  const event = {
68
78
  detail: eventData,
@@ -156,7 +166,7 @@ export const CompRenderer = observer(function (props) {
156
166
  // For循环渲染
157
167
  let forList;
158
168
  try {
159
- forList = dataBinds && dataBinds._waFor && dataBinds._waFor(parentForItems);
169
+ forList = dataBinds && dataBinds._waFor && dataBinds._waFor(parentForItems, undefined, context);
160
170
  } catch (e) {
161
171
  forList = [];
162
172
  console.error('_waFor data', e);
@@ -211,6 +221,15 @@ export const CompRenderer = observer(function (props) {
211
221
  ? get(widgetsData, forItemsIndexes)
212
222
  : widgetsData;
213
223
  const domRef = setGetDomApi(currentWidget, props);
224
+
225
+ // 判断为容器组件,则增加一个onDataChange事件
226
+ if (
227
+ componentSchema?.compConfig?.isDataContainer &&
228
+ !emitEvents?.includes('onDataChange')
229
+ ) {
230
+ emitEvents.push('onDataChange');
231
+ }
232
+
214
233
  return (
215
234
  <ForContext.Provider key={index} value={forItems}>
216
235
  <Field
@@ -283,6 +302,14 @@ export const CompRenderer = observer(function (props) {
283
302
  : widgetsData;
284
303
  const domRef = setGetDomApi(currentWidget, props);
285
304
 
305
+ // 判断为容器组件,则增加一个onDataChange事件
306
+ if (
307
+ componentSchema?.compConfig?.isDataContainer &&
308
+ !emitEvents?.includes('onDataChange')
309
+ ) {
310
+ emitEvents.push('onDataChange');
311
+ }
312
+
286
313
  return (
287
314
  <Field
288
315
  data={{
@@ -24,6 +24,8 @@ export function AppRender(props) {
24
24
  rootNode = true,
25
25
  codeContext,
26
26
  scopeContext = {},
27
+ context = {},
28
+ updateContext,
27
29
  } = props;
28
30
  const {
29
31
  'x-props': xProps,
@@ -91,6 +93,8 @@ export function AppRender(props) {
91
93
  virtualFields={virtualFields}
92
94
  codeContext={codeContext}
93
95
  scopeContext={clonedScopeContext}
96
+ context={context}
97
+ updateContext={updateContext}
94
98
  />
95
99
  );
96
100
  }
@@ -102,6 +106,8 @@ export function AppRender(props) {
102
106
  virtualFields={virtualFields}
103
107
  codeContext={codeContext}
104
108
  scopeContext={scopeContext}
109
+ context={context}
110
+ updateContext={updateContext}
105
111
  />
106
112
  );
107
113
  }
@@ -118,6 +124,8 @@ export function AppRender(props) {
118
124
  codeContext={codeContext}
119
125
  scopeContext={scopeContext}
120
126
  genericComp={genericComp}
127
+ context={context}
128
+ updateContext={updateContext}
121
129
  >
122
130
  {children.map((comp) => (
123
131
  <AppRender
@@ -128,6 +136,8 @@ export function AppRender(props) {
128
136
  virtualFields={virtualFields}
129
137
  codeContext={codeContext}
130
138
  scopeContext={scopeContext}
139
+ context={context}
140
+ updateContext={updateContext}
131
141
  />
132
142
  ))}
133
143
  </CompRenderer>
@@ -48,7 +48,7 @@ const virtualFields = {
48
48
  export default function App() {
49
49
  // 检查权限
50
50
  // const [weDaHasLogin, setWeDaHasLogin] = React.useState(false);
51
-
51
+ const [context, setContext] = React.useState({});
52
52
  // 兼容 this.state / $page.state 两种模式
53
53
  const pageCodeContext = createPageApi()
54
54
  const $page = pageCodeContext
@@ -62,6 +62,27 @@ export default function App() {
62
62
  const dataBinds = $page._dataBinds = <%= dataBinds %>;
63
63
  const componentSchema = <%= componentSchema %>;
64
64
 
65
+ /**
66
+ * 更新数据容器的上下文的方法
67
+ * 会传递到事件emit的地方,将从组件获取到的数据data赋值给上下文
68
+ * 当组件卸载时,传过来的data为undefined即可
69
+ * {
70
+ * id1: [{...}],
71
+ * id2: {...},
72
+ * id3: undefined,
73
+ * id4: null,
74
+ * ...
75
+ * }
76
+ * @param id
77
+ * @param data
78
+ */
79
+ const updateContext = (id, data) => {
80
+ if(id) {
81
+ context[id] = { data };
82
+ }
83
+ setContext({ ...context });
84
+ }
85
+
65
86
  Object.assign($page, {
66
87
  id:'<%= pageName %>',
67
88
  state: observable(initPageState),
@@ -77,7 +98,7 @@ export default function App() {
77
98
  });
78
99
  };
79
100
 
80
- $page.widgets = createWidgets(widgetsContext, dataBinds)
101
+ $page.widgets = createWidgets(widgetsContext, dataBinds, context)
81
102
  // widgets 内的 dataBinds 可能需要关联 widgets,需要重新执行 dataBinds
82
103
  retryDataBinds()
83
104
 
@@ -116,6 +137,8 @@ export default function App() {
116
137
  virtualFields={virtualFields}
117
138
  componentSchema={componentSchema}
118
139
  codeContext={pageCodeContext}
140
+ context={context}
141
+ updateContext={updateContext}
119
142
  />
120
143
  </div>
121
144
  );
@@ -117,9 +117,9 @@ export function retryDataBinds(tryTime = 10) {
117
117
  }
118
118
  retryDataBinds(tryTime - 1);
119
119
  }
120
- export function createWidgets(widgetProps, dataBinds) {
120
+ export function createWidgets(widgetProps, dataBinds, context) {
121
121
  const nodeTree = createWidgetTree(widgetProps, dataBinds);
122
- const widgets = runFor(nodeTree, {}, null, null);
122
+ const widgets = runFor(nodeTree, {}, null, null, context);
123
123
  return widgets;
124
124
 
125
125
  /**
@@ -128,9 +128,10 @@ export function createWidgets(widgetProps, dataBinds) {
128
128
  * @param {*} forItems
129
129
  * @param {*} parentLevelWidgets
130
130
  * @param {*} parentWidget
131
+ * @param {*} context
131
132
  * @returns top level widgets or for dispose
132
133
  */
133
- function runFor(curForNode, forItems, parentLevelWidgets, parentWidget) {
134
+ function runFor(curForNode, forItems, parentLevelWidgets, parentWidget, context) {
134
135
  const nodeId = curForNode.id;
135
136
  if (!curForNode.value) {
136
137
  return createSubTree(curForNode, {});
@@ -138,7 +139,7 @@ export function createWidgets(widgetProps, dataBinds) {
138
139
  const dispose = autorun(() => {
139
140
  let forList = [];
140
141
  try {
141
- forList = dataBinds[nodeId]._waFor(forItems);
142
+ forList = dataBinds[nodeId]._waFor(forItems, undefined, context);
142
143
  } catch (e) {
143
144
  console.error('waFor error', e);
144
145
  }
@@ -268,7 +269,8 @@ export function createWidgets(widgetProps, dataBinds) {
268
269
  node,
269
270
  subForItems,
270
271
  widgets,
271
- node.parent && widgets[node.parent.id]
272
+ node.parent && widgets[node.parent.id],
273
+ context
272
274
  );
273
275
  curForNode.id && widgets[curForNode.id]._disposers.push(dispose);
274
276
  }
@@ -9,7 +9,7 @@ import sdk from './weapp-sdk'
9
9
  */
10
10
  export const compLowcodes = {}
11
11
 
12
- export function createComponent(key, behaviors, properties, events, handler, dataBinds, evtListeners, widgetProps, index, lifeCycle, stateFn, computedFuncs, config, libCommonRes) {
12
+ export function createComponent(key, behaviors, properties, events, handler, dataBinds, evtListeners, widgetProps, index, lifeCycle, stateFn, computedFuncs, config, libCommonRes, undefined, context) {
13
13
 
14
14
  compLowcodes[key] = {
15
15
  index,
@@ -41,9 +41,6 @@ export function createComponent(key, behaviors, properties, events, handler, dat
41
41
  },
42
42
  ...properties,
43
43
  },
44
-
45
- data: {},
46
-
47
44
  lifetimes: {
48
45
  created() {
49
46
  this._pageActive = true
@@ -55,7 +52,7 @@ export function createComponent(key, behaviors, properties, events, handler, dat
55
52
 
56
53
  $comp.props.events = createPropEvents(events, this)
57
54
  $comp.widgets = {}
58
- const { widgets, rootWidget: virtualRootWidget } = createWidgets(widgetProps, dataBindsBindContext(dataBinds, $comp), $comp.widgets, this)
55
+ const { widgets, rootWidget: virtualRootWidget } = createWidgets(widgetProps, dataBindsBindContext(dataBinds, $comp), $comp.widgets, context, this)
59
56
  this._virtualRootWidget = virtualRootWidget
60
57
 
61
58
  try {
@@ -13,6 +13,7 @@ export function createPage(
13
13
  dataBinds,
14
14
  app,
15
15
  $page,
16
+ context,
16
17
  ) {
17
18
  $page.state = observable(pageState);
18
19
  let dataset = createDataset($page.uuid);
@@ -47,7 +48,7 @@ export function createPage(
47
48
  attached() {
48
49
  // createWidgets 从上面移到这里是为了 i18n 切换语言的时候页面能生效
49
50
  $page.widgets = {};
50
- const { rootWidget, widgets } = createWidgets(widgetProps, dataBinds, $page.widgets);
51
+ const { rootWidget, widgets } = createWidgets(widgetProps, dataBinds, $page.widgets, context);
51
52
  this._rootWidget = rootWidget;
52
53
  this._widgets = widgets;
53
54
  this._pageActive = true;
@@ -34,9 +34,9 @@ export function resolveWidgetData(props) {
34
34
  }
35
35
 
36
36
 
37
- export function createWidgets(widgetProps, dataBinds, widgetHolder, ownerMpInst) {
37
+ export function createWidgets(widgetProps, dataBinds, widgetHolder, context, ownerMpInst) {
38
38
  const rootNode = createWidgetDataTree(widgetProps, dataBinds)
39
- return createSubWidgetTree(rootNode, widgetProps, dataBinds, ownerMpInst, widgetHolder)
39
+ return createSubWidgetTree(rootNode, widgetProps, dataBinds, ownerMpInst, widgetHolder, undefined, undefined, undefined, undefined, undefined, context)
40
40
  }
41
41
 
42
42
  /**
@@ -47,7 +47,7 @@ export function createWidgets(widgetProps, dataBinds, widgetHolder, ownerMpInst)
47
47
  */
48
48
  function createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, widgetHolder = {},
49
49
  index = 0, forItems = {}, ownerForWidgetHolder = null,
50
- failedBinds = [], defaultParent = { children: observable([]), _disposers: [] }) {
50
+ failedBinds = [], defaultParent = { children: observable([]), _disposers: [] }, context = {}) {
51
51
  const indexPostfix = (forItems.lists || []).slice().reverse().map(list => idSeparator + list.currentIndex).join('')
52
52
 
53
53
  // traverse down the tree to set up all widgets
@@ -87,7 +87,7 @@ function createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, wi
87
87
  if (node.forCount === curForNode.forCount + 1 && dataBinds[node.id] && dataBinds[node.id]._waFor) {
88
88
  // find the node bound with next level for
89
89
  const parent = node.parent ? widgetHolder[node.parent.id] : defaultParent
90
- const dispose = runFor(node, widgetProps, dataBinds, ownerMpInst, forItems, widgetHolder, failedBinds, parent)
90
+ const dispose = runFor(node, widgetProps, dataBinds, ownerMpInst, forItems, widgetHolder, failedBinds, parent, context)
91
91
  parent._disposers.push(dispose) // Add the for bind dispose to the parent node of forNode
92
92
  }
93
93
  })
@@ -110,12 +110,12 @@ function createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, wi
110
110
  * @param {*} parentWidget
111
111
  * @returns top level widgets or for dispose
112
112
  */
113
- function runFor(curForNode, widgetProps, dataBinds, ownerMpInst, forItems, ownerForWidgetHolder, failedBinds, defaultParent) {
113
+ function runFor(curForNode, widgetProps, dataBinds, ownerMpInst, forItems, ownerForWidgetHolder, failedBinds, defaultParent, context) {
114
114
  const nodeId = curForNode.id
115
115
  const dispose = autorun(() => {
116
116
  let forList = []
117
117
  try {
118
- forList = dataBinds[nodeId]._waFor(forItems.lists, forItems.itemsById)
118
+ forList = dataBinds[nodeId]._waFor(forItems.lists, forItems.itemsById, undefined, context)
119
119
  if (!Array.isArray(forList)) {
120
120
  forList = []
121
121
  }
@@ -153,7 +153,7 @@ function runFor(curForNode, widgetProps, dataBinds, ownerMpInst, forItems, owner
153
153
  lists: [{ currentItem: item, currentIndex: index }, ...lists],
154
154
  itemsById: { ...itemsById, [nodeId]: item },
155
155
  }
156
- const { rootWidget } = createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, {}, index, _forItems, ownerForWidgetHolder, failedBinds, defaultParent)
156
+ const { rootWidget } = createSubWidgetTree(curForNode, widgetProps, dataBinds, ownerMpInst, {}, index, _forItems, ownerForWidgetHolder, failedBinds, defaultParent, context)
157
157
  rootWidget._forItems = _forItems
158
158
  })
159
159
  })
@@ -1,3 +1,4 @@
1
+ import { observable } from 'mobx';
1
2
  import { createComponent } from '../../../common/weapp-component'
2
3
  import { mpCompToWidget } from '../../../common/widget'
3
4
  import { concatClassList, px2rpx } from '../../../common/style'
@@ -11,6 +12,8 @@ import _handler<%= h %> from './lowcode/handler/<%= h %>' <%}) %>
11
12
  import * as constObj from '../libCommonRes/const'
12
13
  import * as toolsObj from '../libCommonRes/tools'
13
14
 
15
+ const context = observable({});
16
+
14
17
  const libCode = '<%= materialName %>'
15
18
 
16
19
  const widgetProps = <%= stringifyObj(widgetProps, {depth: null}) %>
@@ -21,7 +24,7 @@ const evtListeners = {<% Object.entries(eventHandlers).map(([handlerName, listen
21
24
  key: '<%= l.key %>',
22
25
  handler: <% if (l.type == 'rematch') {%> _handler<%= l.handler %> <%} else {%> <%= l.handler %> <%} %>,
23
26
  data: <%= stringifyObj(l.data, {depth: null}) %>,
24
- boundData: {<% Object.entries(l.boundData).map(([prop, expr])=>{%>'<%= prop %>':(lists, forItems, event) => {const $for=forItems;return <%= expr %>},
27
+ boundData: {<% Object.entries(l.boundData).map(([prop, expr])=>{%>'<%= prop %>':(lists, forItems, event, $context) => {const $for=forItems; return <%= expr %>},
25
28
  <%}) %>}
26
29
  },<%})%>
27
30
  ],<%})%>
@@ -49,11 +52,11 @@ const handler = {<% handlers.forEach(h => {%>
49
52
 
50
53
  const dataBinds = {<% Object.entries(dataBinds).map(([id, widgetBinds])=>{%>
51
54
  <%= id %>: { <% Object.entries(widgetBinds).map(([prop, expr]) => { %>
52
- <%= prop %>: function (lists, forItems, event) {const $for=forItems; return <%= expr %>; },<% }) %>
55
+ <%= prop %>: function (lists, forItems, event, $context) {const $for=forItems; return <%= expr %>; },<% }) %>
53
56
  },<%}) %>
54
57
  }
55
58
 
56
59
  const config = <%= JSON.stringify(config || {})%>
57
60
 
58
61
  createComponent('<%= key %>', behaviors, properties, events, handler, dataBinds, evtListeners, widgetProps,
59
- index, lifeCycle, stateFn, computedFuncs, config, { const: constObj, tools: toolsObj }, libCode)
62
+ index, lifeCycle, stateFn, computedFuncs, config, { const: constObj, tools: toolsObj }, libCode, context)
@@ -3,7 +3,7 @@
3
3
  "version": "1.0.0",
4
4
  "scripts": { },
5
5
  "dependencies": {
6
- "@cloudbase/weda-cloud-sdk": "1.0.1",
6
+ "@cloudbase/weda-cloud-sdk": "1.0.1",
7
7
  "mobx": "^5.15.4",
8
8
  "lodash.get": "^4.4.2",
9
9
  "lodash.set": "^4.3.2",
@@ -1,3 +1,4 @@
1
+ import { observable } from 'mobx';
1
2
  import { createPage } from '<%= subLevelPath %>../../common/weapp-page'
2
3
  import { mpCompToWidget } from '<%= subLevelPath %>../../common/widget'
3
4
  import { concatClassList, px2rpx } from '<%= subLevelPath %>../../common/style'
@@ -8,6 +9,7 @@ import lifecyle from '../../lowcode/<%= pageName %>/lifecycle'
8
9
  import state from '../../lowcode/<%= pageName %>/state'
9
10
  import computed from '../../lowcode/<%= pageName %>/computed'
10
11
 
12
+ const context = observable({});
11
13
 
12
14
  const widgetProps = <%= stringifyObj(widgetProps, {depth: null}) %>
13
15
  /** widget event listeners **/
@@ -17,18 +19,18 @@ const evtListeners = {<% Object.entries(eventHanlders).map(([handlerName, listen
17
19
  key: '<%= l.key %>',
18
20
  handler: <% if (l.type === 'rematch') {%> handlers.<%= l.handler %> <%} else if (l.type == 'material') {%> function(...args) { return require('../../materials/<%= l.handlerModule %>/actions/<%= l.handler %>/index').default(...args) } <%} else {%> <%= l.handler %> <%} %>,
19
21
  data: <%= stringifyObj(l.data, {depth: null}) %>,
20
- boundData: {<% Object.entries(l.boundData).map(([prop, expr])=>{%>'<%= prop %>':(lists, forItems, event) => {const $for = forItems; return <%= expr %>},
22
+ boundData: {<% Object.entries(l.boundData).map(([prop, expr])=>{%>'<%= prop %>':(lists, forItems, event, $context) => {const $for = forItems; return <%= expr %>},
21
23
  <%}) %>}
22
24
  },<%})%>
23
25
  ],<%})%>
24
26
  }
25
27
  const dataBinds = {<% Object.entries(dataBinds).map(([id, widgetBinds])=>{%>
26
28
  <%= id %>: { <% Object.entries(widgetBinds).map(([prop, expr]) => { %>
27
- <%= prop %>: function (lists, forItems, event) {const $for = forItems; return <%= expr %>; },<% }) %>
29
+ <%= prop %>: function (lists, forItems, event, $context) {const $for = forItems; return <%= expr %>; },<% }) %>
28
30
  },<%}) %>
29
31
  }
30
32
 
31
33
  $page.id = '<%= pageName %>'
32
34
  $page.uuid = '<%= pageUUID %>'
33
35
  $page.handler = handlers
34
- createPage(lifecyle, widgetProps, state, computed, evtListeners, dataBinds, app, $page)
36
+ createPage(lifecyle, widgetProps, state, computed, evtListeners, dataBinds, app, $page, context)
@@ -24,6 +24,8 @@ export const CompRenderer = observer(function (props) {
24
24
  slots = {},
25
25
  codeContext,
26
26
  scopeContext,
27
+ context = {},
28
+ updateContext,
27
29
  emitEvents = [],
28
30
  componentSchema = {},
29
31
  } = props;
@@ -62,6 +64,13 @@ export const CompRenderer = observer(function (props) {
62
64
  // 组件最终用于执行的事件函数
63
65
  const emit = useCallback(
64
66
  (trigger, event, forItems, scopeContext) => {
67
+ // 如果是数据容器,则将传过来的data,赋值给容器上下文context
68
+ if (
69
+ trigger === 'onDataChange' &&
70
+ componentSchema?.compConfig?.isDataContainer
71
+ ) {
72
+ updateContext(compId, event?.data);
73
+ }
65
74
  const listeners = listenerInstances;
66
75
  event = { detail: event, name: trigger };
67
76
  forItems = {
@@ -142,7 +151,7 @@ export const CompRenderer = observer(function (props) {
142
151
  try {
143
152
  // 绑定了 for 变量,但计算值错误时,应当空数组兜底
144
153
  forList =
145
- dataBinds && dataBinds._waFor && (dataBinds._waFor(parentForItems) || []);
154
+ dataBinds && dataBinds._waFor && (dataBinds._waFor(parentForItems, undefined, context) || []);
146
155
  } catch (e) {
147
156
  // 计算值出错则使用空数组兜底
148
157
  forList = [];
@@ -197,6 +206,15 @@ export const CompRenderer = observer(function (props) {
197
206
  classNameList: forItemClassNameList,
198
207
  staticResourceAttribute,
199
208
  });
209
+
210
+ // 判断为容器组件,则增加一个onDataChange事件
211
+ if (
212
+ componentSchema?.compConfig?.isDataContainer &&
213
+ !emitEvents?.includes('onDataChange')
214
+ ) {
215
+ emitEvents.push('onDataChange');
216
+ }
217
+
200
218
  return (
201
219
  <ForContext.Provider key={index} value={forItems}>
202
220
  <Field
@@ -263,6 +281,15 @@ export const CompRenderer = observer(function (props) {
263
281
  classNameList: finalClassNameList,
264
282
  staticResourceAttribute,
265
283
  });
284
+
285
+ // 判断为容器组件,则增加一个onDataChange事件
286
+ if (
287
+ componentSchema?.compConfig?.isDataContainer &&
288
+ !emitEvents?.includes('onDataChange')
289
+ ) {
290
+ emitEvents.push('onDataChange');
291
+ }
292
+
266
293
  return (
267
294
  <Field
268
295
  data={{ ...fieldData, _selectableBlockEvents: _selectableBlockEventsWithItem }}
@@ -23,6 +23,8 @@ export function AppRender(props) {
23
23
  rootNode = true,
24
24
  codeContext,
25
25
  scopeContext = {},
26
+ context = {},
27
+ updateContext,
26
28
  } = props;
27
29
 
28
30
  const { 'x-props': xProps, properties = {} } = componentSchema;
@@ -89,6 +91,8 @@ export function AppRender(props) {
89
91
  virtualFields={virtualFields}
90
92
  codeContext={codeContext}
91
93
  scopeContext={clonedScopeContext}
94
+ context={context}
95
+ updateContext={updateContext}
92
96
  />
93
97
  );
94
98
  }
@@ -100,6 +104,8 @@ export function AppRender(props) {
100
104
  virtualFields={virtualFields}
101
105
  codeContext={codeContext}
102
106
  scopeContext={scopeContext}
107
+ context={context}
108
+ updateContext={updateContext}
103
109
  />
104
110
  );
105
111
  }
@@ -115,6 +121,8 @@ export function AppRender(props) {
115
121
  slots={slots}
116
122
  codeContext={codeContext}
117
123
  scopeContext={scopeContext}
124
+ context={context}
125
+ updateContext={updateContext}
118
126
  >
119
127
  {children.map((comp) => (
120
128
  <AppRender
@@ -125,6 +133,8 @@ export function AppRender(props) {
125
133
  virtualFields={virtualFields}
126
134
  codeContext={codeContext}
127
135
  scopeContext={scopeContext}
136
+ context={context}
137
+ updateContext={updateContext}
128
138
  />
129
139
  ))}
130
140
  </CompRenderer>