diff --git a/packages/core/src/App.ts b/packages/core/src/App.ts index aa9cf1b2..66172944 100644 --- a/packages/core/src/App.ts +++ b/packages/core/src/App.ts @@ -263,10 +263,10 @@ class App extends EventEmitter implements AppCore { if (!this.page) return; for (const [, value] of this.page.nodes) { - value.events?.forEach((event) => { + value.events?.forEach((event, index) => { const eventName = `${event.name}_${value.data.id}`; const eventHandler = (fromCpt: Node, ...args: any[]) => { - this.eventHandler(event, fromCpt, args); + this.eventHandler(index, fromCpt, args); }; this.eventList.set(eventHandler, eventName); this.on(eventName, eventHandler); @@ -358,15 +358,18 @@ class App extends EventEmitter implements AppCore { /** * 事件联动处理函数 - * @param eventConfig 事件配置 + * @param eventsConfigIndex 事件配置索引,可以通过此索引从node.event中获取最新事件配置 * @param fromCpt 触发事件的组件 * @param args 事件参数 */ - private async eventHandler(eventConfig: EventConfig | DeprecatedEventConfig, fromCpt: any, args: any[]) { + private async eventHandler(eventsConfigIndex: number, fromCpt: Node, args: any[]) { + const eventConfig = fromCpt.events[eventsConfigIndex] as EventConfig | DeprecatedEventConfig; if (has(eventConfig, 'actions')) { // EventConfig类型 const { actions } = eventConfig as EventConfig; - for (const actionItem of actions) { + for (let i = 0; i < actions.length; i++) { + // 事件响应中可能会有修改数据源数据的,会更新dsl,所以这里需要重新获取 + const actionItem = (fromCpt.events[eventsConfigIndex] as EventConfig).actions[i]; if (actionItem.actionType === ActionType.COMP) { // 组件动作 await this.compActionHandler(actionItem as CompItemConfig, fromCpt, args); diff --git a/packages/core/src/Node.ts b/packages/core/src/Node.ts index 01b2779a..3a181fd9 100644 --- a/packages/core/src/Node.ts +++ b/packages/core/src/Node.ts @@ -41,11 +41,11 @@ interface NodeOptions { app: App; } class Node extends EventEmitter { - public data: MComponent | MContainer | MPage | MPageFragment; + public data!: MComponent | MContainer | MPage | MPageFragment; public style?: { [key: string]: any; }; - public events: DeprecatedEventConfig[] | EventConfig[]; + public events: DeprecatedEventConfig[] | EventConfig[] = []; public instance?: any; public page?: Page; public parent?: Node; @@ -58,14 +58,15 @@ class Node extends EventEmitter { this.page = options.page; this.parent = options.parent; this.app = options.app; - const { events } = options.config; - this.data = options.config; - this.events = events || []; + this.setData(options.config); this.listenLifeSafe(); } public setData(data: MComponent | MContainer | MPage | MPageFragment) { this.data = data; + const { events, style } = data; + this.events = events || []; + this.style = style || {}; this.emit('update-data'); } diff --git a/packages/core/src/Page.ts b/packages/core/src/Page.ts index 9dc1f7fa..2b439bfa 100644 --- a/packages/core/src/Page.ts +++ b/packages/core/src/Page.ts @@ -32,7 +32,9 @@ class Page extends Node { super(options); this.setNode(options.config.id, this); - this.initNode(options.config, this); + options.config.items.forEach((config) => { + this.initNode(config, this); + }); } public initNode(config: MComponent | MContainer, parent: Node) { diff --git a/packages/data-source/src/createDataSourceManager.ts b/packages/data-source/src/createDataSourceManager.ts index f3aab67b..f911d4f9 100644 --- a/packages/data-source/src/createDataSourceManager.ts +++ b/packages/data-source/src/createDataSourceManager.ts @@ -18,7 +18,7 @@ import { union } from 'lodash-es'; import type { AppCore } from '@tmagic/schema'; -import { getDepNodeIds, getNodes } from '@tmagic/utils'; +import { getDepNodeIds, getNodes, isPage } from '@tmagic/utils'; import DataSourceManager from './DataSourceManager'; import type { ChangeEvent, DataSourceManagerData } from './types'; @@ -66,7 +66,18 @@ export const createDataSourceManager = (app: AppCore, useMock?: boolean, initial node.condResult = dataSourceManager.compliedConds(node); } - return dataSourceManager.compiledNode(node); + const newNode = dataSourceManager.compiledNode(node); + + if (typeof app.page?.setData === 'function') { + if (isPage(newNode)) { + app.page.setData(newNode); + } else { + const n = app.page.getNode(node.id); + n?.setData(newNode); + } + } + + return newNode; }), sourceId, changeEvent, diff --git a/packages/data-source/src/utils.ts b/packages/data-source/src/utils.ts index 57163bdf..9343e6de 100644 --- a/packages/data-source/src/utils.ts +++ b/packages/data-source/src/utils.ts @@ -15,6 +15,12 @@ import { import type { AsyncDataSourceResolveResult, DataSourceManagerData } from './types'; +/** + * 编译数据源条件组 + * @param node dsl节点 + * @param data 数据源数据 + * @returns boolean + */ export const compliedConditions = (node: MNode, data: DataSourceManagerData) => { if (!node.displayConds || !Array.isArray(node.displayConds) || !node.displayConds.length) return true; @@ -56,6 +62,13 @@ export const updateNode = (node: MNode, dsl: MApp) => { } }; +/** + * 创建迭代器容器编译的数据上下文 + * @param itemData 迭代数据 + * @param dsId 数据源id + * @param fields dsl节点字段,如a.b.c + * @returns 数据上下文 + */ export const createIteratorContentData = (itemData: any, dsId: string, fields: string[] = []) => { const data = { [dsId]: {}, @@ -70,6 +83,15 @@ export const createIteratorContentData = (itemData: any, dsId: string, fields: s return data; }; +/** + * 编译通过tmagic-editor的数据源源选择器配(data-source-field-select) + * 格式为 [`${DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX}${id}`, 'field'] + * DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX常量可通过@tmagic/utils获取 + * + * @param value dsl节点中的数据源配置 + * @param data 数据源数据 + * @returns 编译好的配置 + */ export const compliedDataSourceField = (value: any, data: DataSourceManagerData) => { const [prefixId, ...fields] = value; const prefixIndex = prefixId.indexOf(DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX); @@ -87,6 +109,12 @@ export const compliedDataSourceField = (value: any, data: DataSourceManagerData) return value; }; +/** + * 编译通过tmagic-editor的数据源源选择器(data-source-input,data-source-select,data-source-field-select)配置出来的数据,或者其他符合规范的配置 + * @param value dsl节点中的数据源配置 + * @param data 数据源数据 + * @returns 编译好的配置 + */ export const compiledNodeField = (value: any, data: DataSourceManagerData) => { // 使用data-source-input等表单控件配置的字符串模板,如:`xxx${id.field}xxx` if (typeof value === 'string') {