` | 全选时触发 |
+> `[name]`表示当前组件绑定的名称,即`name`属性,如果没有配置`name`属性,则通过`value`取值。
+
+| 事件名称 | 事件参数 | 说明 |
+| --------- | --------------------------------------------------------------------------------------- | ---------------- |
+| change | `[name]: string` 组件的值
`items: object[]`选中项(< 2.3.2 及以下版本 为`options`) | 选中值变化时触发 |
+| selectAll | `items: object[]`选项集合(< 2.3.2 及以下版本 为`options`) | 全选时触发 |
## 动作表
当前组件对外暴露以下特性动作,其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作,动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数,详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。
-| 动作名称 | 动作配置 | 说明 |
-| --------- | ------------------------ | ------------------------------------------------------ |
-| clear | - | 清空 |
-| reset | - | 将值重置为`resetValue`,若没有配置`resetValue`,则清空 |
-| selectAll | - | 全选 |
-| setValue | `value: string` 更新的值 | 更新数据,多值用`,`分隔 |
+| 动作名称 | 动作配置 | 说明 |
+| --------- | -------------------------------------- | --------------------------------------------------------------------------------------- |
+| clear | - | 清空 |
+| reset | - | 将值重置为`resetValue`,若没有配置`resetValue`,则清空 |
+| selectAll | - | 全选 |
+| setValue | `value: string` \| `string[]` 更新的值 | 更新数据,开启`multiple`支持设置多项,开启`joinValues`时,多值用`,`分隔,否则多值用数组 |
diff --git a/docs/zh-CN/components/form/treeselect.md b/docs/zh-CN/components/form/treeselect.md
index 112e9b28d..72a1b4110 100755
--- a/docs/zh-CN/components/form/treeselect.md
+++ b/docs/zh-CN/components/form/treeselect.md
@@ -311,24 +311,26 @@ order: 60
## 事件表
-当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`event.data.xxx`事件参数变量来获取事件产生的数据,详细请查看[事件动作](../../docs/concepts/event-action)。
+当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`${事件参数名}`来获取事件产生的数据(`< 2.3.2 及以下版本 为 ${event.data.[事件参数名]}`),详细请查看[事件动作](../../docs/concepts/event-action)。
-| 事件名称 | 事件参数 | 说明 |
-| ------------ | ------------------------------------------------------------------------------------- | ---------------------------- |
-| change | `event.data.value: string` 选中节点的值 | 选中值变化时触发 |
-| add | `event.data.options: Option[]` 选项集合
`event.data.value: Option` 新增的节点信息 | 新增节点提交时触发 |
-| edit | `event.data.options: Option[]` 选项集合
`event.data.value: Option` 编辑的节点信息 | 编辑节点提交时触发 |
-| delete | `event.data.options: Option[]` 选项集合
`event.data.value: Option` 编辑的节点信息 | 编辑节点提交时触发 |
-| loadFinished | `event.data.value: object` deferApi 懒加载远程请求成功后返回的数据 | 懒加载接口远程请求成功时触发 |
-| blur | `event.data.value: string` 选中值 | 输入框失去焦点时触发 |
-| focus | `event.data.value: string` 选中值 | 输入框获取焦点时触发 |
+> `[name]`表示当前组件绑定的名称,即`name`属性,如果没有配置`name`属性,则通过`value`取值。
+
+| 事件名称 | 事件参数 | 说明 |
+| ------------ | ------------------------------------------------------------------------------------------------ | ---------------------------- |
+| change | `[name]: string` 组件的值 | 选中值变化时触发 |
+| blur | `[name]: string` 组件的值 | 输入框失去焦点时触发 |
+| focus | `[name]: string` 组件的值 | 输入框获取焦点时触发 |
+| add | `[name]: object` 新增的节点信息
``items: object[]`选项集合(< 2.3.2 及以下版本 为`options`) | 新增节点提交时触发 |
+| edit | `[name]: object` 编辑的节点信息
``items: object[]`选项集合(< 2.3.2 及以下版本 为`options`) | 编辑节点提交时触发 |
+| delete | `[name]: object` 编辑的节点信息
``items: object[]`选项集合(< 2.3.2 及以下版本 为`options`) | 编辑节点提交时触发 |
+| loadFinished | `[name]: object` deferApi 懒加载远程请求成功后返回的数据 | 懒加载接口远程请求成功时触发 |
## 动作表
当前组件对外暴露以下特性动作,其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作,动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数,详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。
-| 动作名称 | 动作配置 | 说明 |
-| -------- | ------------------------ | ------------------------------------------------------ |
-| clear | - | 清空 |
-| reset | - | 将值重置为`resetValue`,若没有配置`resetValue`,则清空 |
-| setValue | `value: string` 更新的值 | 更新数据,开启`multiple`,多值用`,`分隔 |
+| 动作名称 | 动作配置 | 说明 |
+| -------- | -------------------------------------- | --------------------------------------------------------------------------------------- |
+| clear | - | 清空 |
+| reset | - | 将值重置为`resetValue`,若没有配置`resetValue`,则清空 |
+| setValue | `value: string` \| `string[]` 更新的值 | 更新数据,开启`multiple`支持设置多项,开启`joinValues`时,多值用`,`分隔,否则多值用数组 |
diff --git a/docs/zh-CN/components/page.md b/docs/zh-CN/components/page.md
index ca47a1127..377bd3be0 100755
--- a/docs/zh-CN/components/page.md
+++ b/docs/zh-CN/components/page.md
@@ -282,12 +282,14 @@ Page 默认将页面分为几个区域,分别是**内容区(`body`)**、**
## 事件表
-当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`event.data.xxx`事件参数变量来获取事件产生的数据,详细请查看[事件动作](../../docs/concepts/event-action)。
+当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`${事件参数名}`来获取事件产生的数据,详细请查看[事件动作](../../docs/concepts/event-action)。
-| 事件名称 | 事件参数 | 说明 |
-| ----------- | --------------------------------------------- | ---------------------------------------------- |
-| inited | `event.data` initApi 远程请求返回的初始化数据 | 远程初始化接口请求成功时触发 |
-| pullRefresh | - | 开启下拉刷新后,下拉释放后触发(仅用于移动端) |
+> `[name]`为当前数据域中的字段名,例如:当前数据域为 {username: 'amis'},则可以通过${username}获取对应的值。
+
+| 事件名称 | 事件参数 | 说明 |
+| ----------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------- |
+| inited | `event.data` initApi 远程请求返回的初始化数据
`[name]: any` 当前数据域中指定字段的值 | 远程初始化接口请求成功时触发 |
+| pullRefresh | - | 开启下拉刷新后,下拉释放后触发(仅用于移动端) |
## 动作表
diff --git a/docs/zh-CN/components/service.md b/docs/zh-CN/components/service.md
index 265d9e1d8..d26f613a3 100755
--- a/docs/zh-CN/components/service.md
+++ b/docs/zh-CN/components/service.md
@@ -699,12 +699,14 @@ ws.on('connection', function connection(ws) {
## 事件表
-当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`event.data.xxx`事件参数变量来获取事件产生的数据,详细请查看[事件动作](../../docs/concepts/event-action)。
+当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`${事件参数名}`来获取事件产生的数据,详细请查看[事件动作](../../docs/concepts/event-action)。
-| 事件名称 | 事件参数 | 说明 |
-| ----------------- | --------------------------------------------- | ---------------------------------- |
-| fetchInited | `event.data` api 远程请求返回的初始化数据 | 远程初始化接口请求成功时触发 |
-| fetchSchemaInited | `event.data` schemaApi 远程请求返回的 UI 内容 | 远程 schemaApi UI 内容接口请求成功 |
+> `[name]`为当前数据域中的字段名,例如:当前数据域为 {username: 'amis'},则可以通过${username}获取对应的值。
+
+| 事件名称 | 事件参数 | 说明 |
+| ----------------- | ---------------------------------------------------------------------------------------- | ---------------------------------- |
+| fetchInited | `event.data` api 远程请求返回的初始化数据
`[name]: any` 当前数据域中指定字段的值 | 远程初始化接口请求成功时触发 |
+| fetchSchemaInited | `event.data` schemaApi 远程请求返回的 UI 内容
`[name]: any` 当前数据域中指定字段的值 | 远程 schemaApi UI 内容接口请求成功 |
## 动作表
diff --git a/docs/zh-CN/components/tabs.md b/docs/zh-CN/components/tabs.md
index e5eb8d4c1..31ed648d2 100755
--- a/docs/zh-CN/components/tabs.md
+++ b/docs/zh-CN/components/tabs.md
@@ -658,11 +658,13 @@ order: 68
## 事件表
-当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`event.data.xxx`事件参数变量来获取事件产生的数据,详细请查看[事件动作](../../docs/concepts/event-action)。
+当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`${事件参数名}`来获取事件产生的数据(`< 2.3.2 及以下版本 为 ${event.data.[事件参数名]}`),详细请查看[事件动作](../../docs/concepts/event-action)。
-| 事件名称 | 事件参数 | 说明 |
-| -------- | ----------------------------------------------- | ---------------- |
-| change | `event.data.value: number \| string` 选项卡索引 | 切换选项卡时触发 |
+> `[name]`表示当前组件绑定的名称,即`name`属性,如果没有配置`name`属性,则通过`value`取值。
+
+| 事件名称 | 事件参数 | 说明 |
+| -------- | ------------------------------------- | ---------------- |
+| change | `[name]: number \| string` 选项卡索引 | 切换选项卡时触发 |
## 动作表
diff --git a/docs/zh-CN/components/wizard.md b/docs/zh-CN/components/wizard.md
index d07c0564f..4cb0d41f4 100755
--- a/docs/zh-CN/components/wizard.md
+++ b/docs/zh-CN/components/wizard.md
@@ -15,7 +15,7 @@ order: 73
```schema: scope="body"
{
"type": "wizard",
- "api": "/api/mock2/form/saveForm?waitSeconds=2",
+ "initApi": "/api/mock2/form/saveForm?waitSeconds=2",
"mode": "vertical",
"steps": [
{
@@ -96,18 +96,20 @@ order: 73
## 事件表
-当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`event.data.xxx`事件参数变量来获取事件产生的数据,详细请查看[事件动作](../../docs/concepts/event-action)。
+当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`${事件参数名}`来获取事件产生的数据,详细请查看[事件动作](../../docs/concepts/event-action)。
-| 事件名称 | 事件参数 | 说明 |
-| -------------- | -------------------------------------------------------------------- | ---------------------------- |
-| inited | `event.data: object` initApi 远程请求返回的初始化数据 | 远程初始化接口请求成功时触发 |
-| stepChange | `event.data.step: number` 步骤索引 | 切换步骤时触发 |
-| change | `event.data: object` 当前表单数据 | 表单值变化时触发 |
-| stepSubmitSucc | - | 单个步骤提交成功 |
-| stepSubmitFail | `event.data.error: object` 单个步骤 api 远程请求失败后返回的错误信息 | 单个步骤提交失败 |
-| finished | `event.data: object` 即将提交的表单数据 | 最终提交时触发 |
-| submitSucc | `event.data.result: object` api 远程请求成功后返回的结果数据 | 最终提交成功时触发 |
-| submitFail | `event.data.error: object` api 远程请求失败后返回的错误信息 | 最终提交失败时触发 |
+> `[name]`为当前数据域中的字段名,例如:当前数据域为 {username: 'amis'},则可以通过${username}获取对应的值。
+
+| 事件名称 | 事件参数 | 说明 |
+| -------------- | ------------------------------------------------------------------------------------------------ | ---------------------------- |
+| inited | `event.data: object` initApi 远程请求返回的初始化数据
`[name]: any` 当前数据域中指定字段的值 | 远程初始化接口请求成功时触发 |
+| stepChange | `step: number` 步骤索引 | 切换步骤时触发 |
+| change | `event.data: object` 当前表单数据
`[name]: any` 当前数据域中指定字段的值 | 表单值变化时触发 |
+| stepSubmitSucc | - | 单个步骤提交成功 |
+| stepSubmitFail | `error: object` 单个步骤 api 远程请求失败后返回的错误信息 | 单个步骤提交失败 |
+| finished | `event.data: object` 即将提交的表单数据
`[name]: any` 当前数据域中指定字段的值 | 最终提交时触发 |
+| submitSucc | `result: object` api 远程请求成功后返回的结果数据 | 最终提交成功时触发 |
+| submitFail | `error: object` api 远程请求失败后返回的错误信息 | 最终提交失败时触发 |
## 动作表
diff --git a/docs/zh-CN/concepts/event-action.md b/docs/zh-CN/concepts/event-action.md
index b0e4f4c6c..cfb0c8768 100644
--- a/docs/zh-CN/concepts/event-action.md
+++ b/docs/zh-CN/concepts/event-action.md
@@ -97,10 +97,20 @@ order: 9
通过配置`actionType: 'ajax'`和`api`实现 http 请求发送,该动作需实现 `env.fetcher` 请求器。
-- 请求结果缓存在`event.data.responseResult`或`event.data.{{outputVar}}`。
-- 请求结果的状态、数据、消息分别默认缓存在:`event.data.{{outputVar}}.responseStatus`、`event.data.{{outputVar}}.responseData`、`event.data.{{outputVar}}.responseMsg`。
+请求响应结果缓存在`responseResult`或`{outputVar}`(`< 2.3.2 及以下版本 为 event.data.responseResult`或`event.data.{outputVar}`)。请求响应结果的结构如下:
-< 2.0.3 及以下版本,请求返回数据默认缓存在 `event.data`。`outputVar` 配置用于解决串行或者并行发送多个 http 请求的场景。
+```json
+{
+ // 状态码
+ "responseStatus": 0,
+ // 响应数据
+ "responseData": {
+ "xxx": "xxx"
+ },
+ // 响应消息
+ "responseMsg": "ok"
+}
+```
```schema
{
@@ -134,9 +144,9 @@ order: 9
},
{
actionType: 'toast',
- expression: '${event.data.responseResult.responseStatus === 0}',
+ expression: '${responseResult.responseStatus === 0}',
args: {
- msg: '${event.data|json}'
+ msg: '${responseResult|json}'
}
}
]
@@ -172,9 +182,9 @@ order: 9
},
{
actionType: 'toast',
- expression: '${event.data.responseResult.responseStatus === 0}',
+ expression: '${responseResult.responseStatus === 0}',
args: {
- msg: '${event.data|json}'
+ msg: '${responseResult|json}'
}
}
]
@@ -187,12 +197,13 @@ order: 9
**动作属性**
-| 属性名 | 类型 | 默认值 | 说明 |
-| ------------- | ----------------------------------- | ------ | ----------------------------------------------------------- |
-| actionType | `string` | `ajax` | ajax 请求 |
-| args.api | [API](../../../docs/types/api) | - | 接口配置,`< 1.8.0 及以下版本 为 api` |
-| args.options | `object` | - | 其他配置,`< 1.8.0 及以下版本 为 options` |
-| args.messages | `{success: string, failed: string}` | - | 请求成功/失败后的提示信息,`< 1.8.0 及以下版本 为 messages` |
+| 属性名 | 类型 | 默认值 | 说明 |
+| ------------- | ----------------------------------- | ------ | ---------------------------------------------------------------------------------- |
+| actionType | `string` | `ajax` | ajax 请求 |
+| args.api | [API](../../../docs/types/api) | - | 接口配置,`< 1.8.0 及以下版本 为 api` |
+| args.options | `object` | - | 其他配置,`< 1.8.0 及以下版本 为 options` |
+| args.messages | `{success: string, failed: string}` | - | 请求成功/失败后的提示信息,`< 1.8.0 及以下版本 为 messages` |
+| outputVar | `string` | - | 输出数据变量名,用于存储请求响应结果,用于解决串行或者并行发送多个 http 请求的场景 |
### 打开弹窗(模态)
@@ -275,9 +286,9 @@ order: 9
**动作属性**
-| 属性名 | 类型 | 默认值 | 说明 |
-| ---------- | ----------------------- | -------- | ------------------------------------------ |
-| actionType | `string` | `dialog` | 点击后显示一个弹出框 |
+| 属性名 | 类型 | 默认值 | 说明 |
+| ---------- | ----------------------- | -------- | --------------------------------------------------------- |
+| actionType | `string` | `dialog` | 点击后显示一个弹出框 |
| dialog | `string`/`DialogObject` | - | 指定弹框内容,格式可参考[Dialog](../../components/dialog) |
### 关闭弹窗(模态)
@@ -430,9 +441,9 @@ order: 9
**动作属性**
-| 属性名 | 类型 | 默认值 | 说明 |
-| ---------- | ----------------------- | -------- | ------------------------------------------ |
-| actionType | `string` | `drawer` | 点击后显示一个侧边栏 |
+| 属性名 | 类型 | 默认值 | 说明 |
+| ---------- | ----------------------- | -------- | --------------------------------------------------------- |
+| actionType | `string` | `drawer` | 点击后显示一个侧边栏 |
| drawer | `string`/`DrawerObject` | - | 指定弹框内容,格式可参考[Drawer](../../components/drawer) |
### 关闭抽屉(模态)
@@ -1367,7 +1378,7 @@ order: 9
更新数据即更新指定组件数据域中的数据(data),通过配置`actionType: 'setValue'`实现组件`数据域变量更新`,通过它可以实现`组件间联动更新`、`数据回填`,支持`基础类型`、`对象类型`、`数组类型`,数据类型取决于目标组件所需数据值类型,仅支持`form`、`dialog`、`drawer`、`wizard`、`service`、`page`、`app`、`chart`,以及数据`输入类`组件。更多示例请查看[更新数据示例](../../../examples/action/setdata/form)。
-> 注意:虽然更新数据可以实现对组件数据域的更新,但如果更新数据动作的数据值来自前面的异步动作(例如 发送 http 请求、自定义 JS(异步)),则后面的动作只能通过事件变量`${event.data.xxx}`来获取异步动作产生的数据,无法通过当前数据域`${xxx}`直接获取更新后的数据。
+> 注意:< 2.3.2 及以下版本,虽然更新数据可以实现对组件数据域的更新,但如果更新数据动作的数据值来自前面的异步动作(例如 发送 http 请求、自定义 JS(异步)),则后面的动作只能通过事件变量`${event.data.xxx}`来获取异步动作产生的数据,无法通过当前数据域`${xxx}`直接获取更新后的数据。
```schema
{
@@ -1444,7 +1455,7 @@ order: 9
- context,渲染器上下文
- doAction() 动作执行方法,用于调用任何 actionType 指定的动作
-- event,事件对象,可以获取事件上下文,以及可以调用 setData()、stopPropagation()、preventDefault()分别实现事件上下文设置、动作干预、事件干预
+- event,事件对象,可以调用 setData()、stopPropagation()、preventDefault()分别实现事件上下文设置、动作干预、事件干预,可以通过 event.data 获取事件上下文
```schema
{
@@ -1507,7 +1518,7 @@ order: 9
{
"componentId": "u:e47e2c8e6be8",
"args": {
- "value": "${event.data.pId}"
+ "value": "${pId}"
},
"actionType": "setValue"
},
@@ -1563,7 +1574,7 @@ order: 9
{
"componentId": "u:e47e2c8e6be7",
"args": {
- "value": "${event.data.pId}"
+ "value": "${pId}"
},
"actionType": "setValue"
},
@@ -1711,7 +1722,7 @@ order: 9
{
actionType: 'reload',
args: {
- myname: '${event.data.value}', // 从事件数据中取
+ myname: '${myrole}', // 从事件数据中取
}
},
{
@@ -1753,8 +1764,8 @@ order: 9
{
actionType: 'reload',
args: {
- myrole: '${event.data.value}',
- age: '${event.data.age}'
+ myrole: '${myrole}',
+ age: '${age}'
}
},
{
@@ -1791,7 +1802,7 @@ order: 9
{
actionType: 'reload',
args: {
- job: '${event.data.value}'
+ job: '${myrole}'
}
},
{
@@ -2294,6 +2305,10 @@ registerAction('my-action', new MyAction());
body: {
type: 'form',
wrapWithPanel: false,
+ data: {
+ name: 'lvxj',
+ age: 'kkkk'
+ },
body: [
{
type: 'button',
@@ -2332,13 +2347,27 @@ registerAction('my-action', new MyAction());
}
},
outputVar: 'var2'
+ },
+ {
+ actionType: 'ajax',
+ args: {
+ api: {
+ url: 'https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm?name=${name}',
+ method: 'get'
+ },
+ messages: {
+ success: '请求3成功了!欧耶',
+ failed: '失败了呢。。'
+ }
+ },
+ outputVar: 'var3'
}
]
},
{
actionType: 'toast',
args: {
- msg: 'var1:${event.data.var1|json}, var2:${event.data.var2|json}'
+ msg: 'var1:${var1|json}, var2:${var2|json}, var3:${var3|json}'
}
}
]
@@ -2359,7 +2388,7 @@ registerAction('my-action', new MyAction());
# 动作间数据传递
-从事件触发开始,整个数据流包含事件本身产生的事件数据和动作产生的动作数据,事件源头产生的数据在 AMIS 事件动作机制底层已经自动加入渲染器数据域,可以通过`event.data.xxx`直接获取,而部分动作产生的数据如何流动需要交互设计者进行介入,对于数据流动可以通过数据映射,将上一个动作产生的数据作为动作参数写入下一个动作。
+从事件触发开始,整个数据流包含事件本身产生的事件数据和动作产生的动作数据,事件源头产生的数据在 AMIS 事件动作机制底层已经自动加入渲染器数据域,可以通过`xxx`直接获取(`< 2.3.2 及以下版本 为 event.data.xxx`),而部分动作产生的数据如何流动需要交互设计者进行介入,对于数据流动可以通过数据映射,将上一个动作产生的数据作为动作参数写入下一个动作。
**传递数据**
@@ -2416,7 +2445,8 @@ registerAction('my-action', new MyAction());
{
actionType: 'reload',
args: {
- age: '${event.data.age}'
+ age: '${age}',
+ name: '${name}'
}
}
]
@@ -2429,7 +2459,9 @@ registerAction('my-action', new MyAction());
**引用 http 请求动作返回的数据**
-http 请求动作执行结束后,后面的动作可以通过 `event.data.responseResult.responseStatus`或`event.data.{{outputVar}}.responseStatus`、`event.data.responseResult.responseData`或`event.data.{{outputVar}}.responseData`、`event.data.responseResult.responseMsg`或`event.data.{{outputVar}}.responseMsg`来获取请求结果的状态、数据、消息。
+http 请求动作执行结束后,后面的动作可以通过 `${responseResult}`或`${{outputVar}}`来获取请求响应结果,响应结果的结构定义参考[发送 http 请求](../../docs/concepts/event-action#发送-http-请求)。
+
+> `< 2.3.2 及以下版本 需要通过 ${event.data.{xxx}}`来获取以上信息,例如:${event.data.responseResult}
```schema
{
@@ -2451,7 +2483,7 @@ http 请求动作执行结束后,后面的动作可以通过 `event.data.respo
{
actionType: 'dialog',
args: {
- id: '${event.data.responseResult.responseData.id}'
+ id: '${responseResult.responseData.id}'
},
dialog: {
type: 'dialog',
@@ -2531,7 +2563,7 @@ http 请求动作执行结束后,后面的动作可以通过 `event.data.respo
args: {
msg: '不关闭'
},
- preventDefault: 'event.data.command === "Do not close"'
+ preventDefault: 'command === "Do not close"'
}
]
}
diff --git a/examples/components/EventAction/cmpt-event-action/CarouselEvent.jsx b/examples/components/EventAction/cmpt-event-action/CarouselEvent.jsx
index a822a1632..6bab364c2 100644
--- a/examples/components/EventAction/cmpt-event-action/CarouselEvent.jsx
+++ b/examples/components/EventAction/cmpt-event-action/CarouselEvent.jsx
@@ -84,7 +84,7 @@ export default {
{
actionType: 'toast',
args: {
- msg: '滚动至${event.data.activeIndex}'
+ msg: '滚动至${activeIndex}'
}
}
]
diff --git a/examples/components/EventAction/cmpt-event-action/ExcelEvent.jsx b/examples/components/EventAction/cmpt-event-action/ExcelEvent.jsx
index 30e6eee9b..0b3f025c4 100644
--- a/examples/components/EventAction/cmpt-event-action/ExcelEvent.jsx
+++ b/examples/components/EventAction/cmpt-event-action/ExcelEvent.jsx
@@ -3,7 +3,7 @@ const changeEvent = {
{
actionType: 'dialog',
args: {
- val: '${event.data.value}'
+ val: '${file}'
},
dialog: {
title: `派发change事件`,
diff --git a/examples/components/EventAction/cmpt-event-action/InputTreeEvent.jsx b/examples/components/EventAction/cmpt-event-action/InputTreeEvent.jsx
index 8b4e81b94..51ad6e6dd 100644
--- a/examples/components/EventAction/cmpt-event-action/InputTreeEvent.jsx
+++ b/examples/components/EventAction/cmpt-event-action/InputTreeEvent.jsx
@@ -135,7 +135,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '派发change事件${event.data.value}'
+ msg: '派发change事件${tree}'
}
}
]
@@ -146,7 +146,14 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '派发add事件${event.data|json}'
+ msg: '派发add事件${tree|json}'
+ }
+ },
+ {
+ actionType: 'toast',
+ args: {
+ msgType: 'info',
+ msg: '派发add事件${items|json}'
}
}
]
@@ -157,7 +164,14 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '派发edit事件${event.data|json}'
+ msg: '派发edit事件${tree|json}'
+ }
+ },
+ {
+ actionType: 'toast',
+ args: {
+ msgType: 'info',
+ msg: '派发edit事件${items|json}'
}
}
]
@@ -168,7 +182,14 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '派发delete事件${event.data|json}'
+ msg: '派发delete事件${tree|json}'
+ }
+ },
+ {
+ actionType: 'toast',
+ args: {
+ msgType: 'info',
+ msg: '派发delete事件${items|json}'
}
}
]
@@ -179,7 +200,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '派发loadFinished事件${event.data.value|json}'
+ msg: '派发loadFinished事件${tree|json}'
}
}
]
diff --git a/examples/components/EventAction/cmpt-event-action/SelectEvent.jsx b/examples/components/EventAction/cmpt-event-action/SelectEvent.jsx
index dddd001c5..959c21d89 100644
--- a/examples/components/EventAction/cmpt-event-action/SelectEvent.jsx
+++ b/examples/components/EventAction/cmpt-event-action/SelectEvent.jsx
@@ -1,14 +1,14 @@
-const change = {
+const change = name => ({
actions: [
{
actionType: 'toast',
args: {
msgType: 'info',
- msg: '派发change事件${event.data.value|json}'
+ msg: `派发change事件\${${name}|json\}`
}
}
]
-};
+});
const add = {
actions: [
@@ -16,7 +16,7 @@ const add = {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '${event.data|json}'
+ msg: 'clear-select: ${clear-select|json},items: ${items|json}'
}
}
]
@@ -28,7 +28,7 @@ const edit = {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '${event.data|json}'
+ msg: 'clear-select: ${clear-select|json},items: ${items|json}'
}
}
]
@@ -40,7 +40,7 @@ const del = {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '${event.data|json}'
+ msg: 'clear-select: ${clear-select|json},items: ${items|json}'
}
}
]
@@ -135,7 +135,7 @@ export default {
removable: true,
options,
onEvent: {
- change,
+ change: change('clear-select'),
blur,
focus,
add,
@@ -188,7 +188,7 @@ export default {
multiple: true,
options,
onEvent: {
- change,
+ change: change('clear-input-tag'),
blur,
focus
}
@@ -250,7 +250,7 @@ export default {
}
],
onEvent: {
- change
+ change: change('clear-matrix-checkboxes')
}
}
]
@@ -294,7 +294,7 @@ export default {
type: 'radios',
options,
onEvent: {
- change
+ change: change('clear-radios')
}
}
]
@@ -365,7 +365,7 @@ export default {
joinValues: true,
delimiter: '。',
onEvent: {
- change,
+ change: change('clear-nested-select'),
blur,
focus
}
@@ -415,7 +415,7 @@ export default {
'/api/mock2/options/chainedOptions?waitSeconds=1&parentId=$parentId&level=$level&maxLevel=4',
value: 'a,b',
onEvent: {
- change,
+ change: change('clear-chained-select'),
blur,
focus
}
@@ -462,7 +462,7 @@ export default {
label: 'clear动作测试',
mode: 'row',
onEvent: {
- change
+ change: change('clear-input-city')
}
}
]
@@ -508,7 +508,7 @@ export default {
mode: 'row',
option: '勾选框',
onEvent: {
- change
+ change: change('clear-checkbox')
}
}
]
@@ -543,7 +543,7 @@ export default {
label: 'clear动作测试',
options,
onEvent: {
- change
+ change: change('clear-checkboxes')
}
}
]
@@ -590,7 +590,7 @@ export default {
type: 'button-group-select',
options,
onEvent: {
- change
+ change: change('clear-options_001')
}
}
]
@@ -624,7 +624,7 @@ export default {
type: 'list-select',
options,
onEvent: {
- change
+ change: change('clear-options_002')
}
}
]
diff --git a/examples/components/EventAction/cmpt-event-action/ServiceEvent.jsx b/examples/components/EventAction/cmpt-event-action/ServiceEvent.jsx
index 5fd0f70ae..4eea90332 100644
--- a/examples/components/EventAction/cmpt-event-action/ServiceEvent.jsx
+++ b/examples/components/EventAction/cmpt-event-action/ServiceEvent.jsx
@@ -39,7 +39,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'success',
- msg: 'API inited: ${event.data.date}'
+ msg: 'API inited: ${date}'
}
}
]
@@ -77,7 +77,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: 'SchemaAPI inited: title: ${event.data.title}'
+ msg: 'SchemaAPI inited: title: ${title}'
}
}
]
diff --git a/examples/components/EventAction/cmpt-event-action/TableEvent.jsx b/examples/components/EventAction/cmpt-event-action/TableEvent.jsx
index d9b13f38c..fcebf8c2f 100644
--- a/examples/components/EventAction/cmpt-event-action/TableEvent.jsx
+++ b/examples/components/EventAction/cmpt-event-action/TableEvent.jsx
@@ -47,7 +47,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '选中${event.data.selectedItems.length}项数据;未选中${event.data.unSelectedItems.length}项数据'
+ msg: '选中${selectedItems.length}项数据;未选中${unSelectedItems.length}项数据'
}
}
]
@@ -80,10 +80,7 @@ export default {
name: 'browser',
label: 'Browser',
filterable: {
- options: [
- 'Internet Explorer 4.0',
- 'Internet Explorer 5.0'
- ]
+ options: ['Internet Explorer 4.0', 'Internet Explorer 5.0']
}
},
@@ -100,7 +97,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '列排序数据:${event.data|json}'
+ msg: 'orderBy:${orderBy},orderDir:${orderDir}'
}
}
]
@@ -111,7 +108,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '列筛选数据:${event.data|json}'
+ msg: 'filterName:${filterName},filterValue:${filterValue}'
}
}
]
@@ -122,7 +119,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '列搜索数据:${event.data|json}'
+ msg: 'searchName:${searchName},searchValue:${searchValue|json}'
}
}
]
@@ -168,7 +165,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '${event.data.movedItems.length}行发生移动'
+ msg: '${movedItems.length}行发生移动'
}
}
]
@@ -214,7 +211,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '当前显示${event.data.columns.length}列'
+ msg: '当前显示${columns.length}列'
}
}
]
@@ -259,7 +256,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '行单击数据:${event.data|json}'
+ msg: '行单击数据:${rowItem|json}'
}
}
]
diff --git a/examples/components/EventAction/cmpt-event-action/TabsEvent.jsx b/examples/components/EventAction/cmpt-event-action/TabsEvent.jsx
index 250883300..0b3332c0d 100644
--- a/examples/components/EventAction/cmpt-event-action/TabsEvent.jsx
+++ b/examples/components/EventAction/cmpt-event-action/TabsEvent.jsx
@@ -92,7 +92,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '切换至选项卡${event.data.value}'
+ msg: '切换至选项卡${tabs-change-receiver}'
}
}
]
diff --git a/examples/components/EventAction/cmpt-event-action/TransferEvent.jsx b/examples/components/EventAction/cmpt-event-action/TransferEvent.jsx
index a02726094..ea4fbf976 100644
--- a/examples/components/EventAction/cmpt-event-action/TransferEvent.jsx
+++ b/examples/components/EventAction/cmpt-event-action/TransferEvent.jsx
@@ -94,7 +94,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '${event.data.value|json}'
+ msg: '${transfer|json}'
}
}
]
@@ -283,7 +283,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '${event.data.value|json}'
+ msg: '${transferEvent7|json}'
}
}
]
@@ -399,7 +399,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '${event.data.value|json}'
+ msg: '${transferEvent10|json}'
}
}
]
@@ -593,7 +593,7 @@ export default {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '${event.data.value|json}'
+ msg: '${transferEvent13|json}'
}
}
]
diff --git a/examples/components/EventAction/cmpt-event-action/UploadEvent.jsx b/examples/components/EventAction/cmpt-event-action/UploadEvent.jsx
index 62f8df7f5..cb19991d6 100644
--- a/examples/components/EventAction/cmpt-event-action/UploadEvent.jsx
+++ b/examples/components/EventAction/cmpt-event-action/UploadEvent.jsx
@@ -5,7 +5,7 @@ const getEventDesc = eventName => {
actionType: 'toast',
args: {
msgType: 'info',
- msg: `派发${eventName}事件` + '${event.data|json}'
+ msg: `派发${eventName}事件` + '${file|json}'
}
}
]
@@ -18,7 +18,7 @@ const change = {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '派发change事件${event.data.file|json}'
+ msg: '派发change事件${file|json}'
}
}
]
diff --git a/examples/components/EventAction/cmpt-event-action/treeSelectEvent.jsx b/examples/components/EventAction/cmpt-event-action/treeSelectEvent.jsx
index 3d770d5a9..be207d68f 100644
--- a/examples/components/EventAction/cmpt-event-action/treeSelectEvent.jsx
+++ b/examples/components/EventAction/cmpt-event-action/treeSelectEvent.jsx
@@ -34,14 +34,14 @@ const options = [
}
];
-const onEvent = {
+const onEvent = name => ({
blur: {
actions: [
{
actionType: 'toast',
args: {
msgType: 'info',
- msg: '派发blur事件${event.data.value|json}'
+ msg: '派发blur事件${' + name + '|json}'
}
}
]
@@ -52,7 +52,7 @@ const onEvent = {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '派发focus事件${event.data.value|json}'
+ msg: '派发focus事件${' + name + '|json}'
}
}
]
@@ -63,7 +63,7 @@ const onEvent = {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '派发change事件${event.data.value|json}'
+ msg: '派发change事件${' + name + '|json}'
}
}
]
@@ -74,7 +74,14 @@ const onEvent = {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '派发add事件${event.data|json}'
+ msg: '派发add事件${' + name + '|json}'
+ }
+ },
+ {
+ actionType: 'toast',
+ args: {
+ msgType: 'info',
+ msg: '派发add事件${items|json}'
}
}
]
@@ -85,7 +92,14 @@ const onEvent = {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '派发edit事件${event.data|json}'
+ msg: '派发edit事件${' + name + '|json}'
+ }
+ },
+ {
+ actionType: 'toast',
+ args: {
+ msgType: 'info',
+ msg: '派发edit事件${items|json}'
}
}
]
@@ -96,7 +110,14 @@ const onEvent = {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '派发delete事件${event.data|json}'
+ msg: '派发delete事件${' + name + '|json}'
+ }
+ },
+ {
+ actionType: 'toast',
+ args: {
+ msgType: 'info',
+ msg: '派发delete事件${items|json}'
}
}
]
@@ -107,12 +128,12 @@ const onEvent = {
actionType: 'toast',
args: {
msgType: 'info',
- msg: '派发loadFinished事件${event.data.value|json}'
+ msg: '派发loadFinished事件${' + name + '|json}'
}
}
]
}
-};
+});
export default {
type: 'page',
@@ -169,7 +190,7 @@ export default {
editable: true,
deferApi: '/api/mock2/form/deferOptions?label=${label}&waitSeconds=2',
options,
- onEvent
+ onEvent: onEvent('tree')
},
{
type: 'tree-select',
@@ -182,7 +203,7 @@ export default {
editable: true,
deferApi: '/api/mock2/form/deferOptions?label=${label}&waitSeconds=2',
options,
- onEvent
+ onEvent: onEvent('tree多选')
}
]
}
diff --git a/examples/components/EventAction/update-data/DataAutoFill.jsx b/examples/components/EventAction/update-data/DataAutoFill.jsx
index 59cbebb92..0d8e94c97 100644
--- a/examples/components/EventAction/update-data/DataAutoFill.jsx
+++ b/examples/components/EventAction/update-data/DataAutoFill.jsx
@@ -9,7 +9,7 @@ export default {
body: [
{
type: 'alert',
- body: '远程请求后、表单提交后,将数据回填给另一个组件。请求返回的数据可以指定存储在`outputVar`变量里,其他动作可以通过`event.data.{{outputVar}}`直接获取该数据。',
+ body: '远程请求后、表单提交后,将数据回填给另一个组件。请求返回的数据可以指定存储在`outputVar`变量里,其他动作可以通过`${[outputVar]}`直接获取该数据。',
level: 'info',
className: 'mb-1'
},
@@ -59,7 +59,7 @@ export default {
actionType: 'setValue',
componentId: 'form_data_001',
args: {
- value: '${event.data.myResult}'
+ value: '${myResult}'
}
}
]
@@ -156,7 +156,7 @@ export default {
actionType: 'setValue',
componentId: 'form_data_002',
args: {
- value: '${event.data.myResult}'
+ value: '${myResult}'
}
},
{
@@ -404,21 +404,21 @@ export default {
actionType: 'setValue',
componentId: 'id',
args: {
- value: '${event.data.value}'
+ value: '${picker}'
}
},
{
actionType: 'setValue',
componentId: 'platform',
args: {
- value: '${event.data.option.platform}'
+ value: '${selectedItems.platform}'
}
},
{
actionType: 'click',
componentId: 'dialog-action',
args: {
- browser: '${event.data.option.browser}'
+ browser: '${selectedItems.browser}'
}
}
]
diff --git a/examples/components/EventAction/update-data/SyncUpdate.jsx b/examples/components/EventAction/update-data/SyncUpdate.jsx
index ad2debe9f..fc4122f36 100644
--- a/examples/components/EventAction/update-data/SyncUpdate.jsx
+++ b/examples/components/EventAction/update-data/SyncUpdate.jsx
@@ -3,7 +3,7 @@ export default {
body: [
{
type: 'alert',
- body: '当某组件的值发生变化时,联动去更新另一个组件的数据,可以通过event.data来获取事件产生的数据,例如输入框change事件的参数是value: string | string[],则可以通过event.data.value来获取输入的值。',
+ body: '当某组件的值发生变化时,联动去更新另一个组件的数据,可以通过${responseResult}来获取事件产生的数据,例如输入框change事件可以通过${[name]}来获取输入的值,name是组件的名称。',
level: 'info',
className: 'mb-1'
},
@@ -15,6 +15,7 @@ export default {
},
{
type: 'input-text',
+ name: 'role',
label: '输入角色',
mode: 'horizontal',
onEvent: {
@@ -25,7 +26,7 @@ export default {
componentId: 'form_data_2',
args: {
value: {
- myrole: '${event.data.value}'
+ myrole: '${role}'
}
}
}
@@ -36,6 +37,7 @@ export default {
{
type: 'input-text',
label: '输入年龄',
+ name: 'age',
mode: 'horizontal',
onEvent: {
change: {
@@ -45,7 +47,7 @@ export default {
componentId: 'form_data_2',
args: {
value: {
- age: '${event.data.value}'
+ age: '${age}'
}
}
}
@@ -107,7 +109,7 @@ export default {
actionType: 'setValue',
componentId: 'input_data_msg2',
args: {
- value: '${event.data.value}'
+ value: '${message}'
}
}
]
@@ -156,7 +158,7 @@ export default {
actionType: 'setValue',
args: {
value: {
- opts: '${optList[event.data.value]}'
+ opts: '${optList[select1]}'
}
},
componentId: 'u:d731760b321e'
diff --git a/examples/components/EventAction/update-data/UpdateDialog.jsx b/examples/components/EventAction/update-data/UpdateDialog.jsx
index 27704456c..11c0dd6f9 100644
--- a/examples/components/EventAction/update-data/UpdateDialog.jsx
+++ b/examples/components/EventAction/update-data/UpdateDialog.jsx
@@ -10,7 +10,7 @@ export default {
body: [
{
type: 'alert',
- body: '这种场景一般用在弹窗内某个异步操作后,数据的回填。请求返回的数据可以指定存储在`outputVar`变量里,其他动作可以通过event.data.{{outputVar}}直接获取该数据。',
+ body: '这种场景一般用在弹窗内某个异步操作后,数据的回填。请求返回的数据可以指定存储在`outputVar`变量里,其他动作可以通过${[outputVar]}直接获取该数据。',
level: 'info',
className: 'mb-1'
},
@@ -77,7 +77,7 @@ export default {
componentId: 'dialog_003',
args: {
value: {
- username: '${event.data.myResult.name}'
+ username: '${myResult.name}'
}
}
}
diff --git a/examples/components/Form/Picker.jsx b/examples/components/Form/Picker.jsx
index 2e17d090f..4515ce1e1 100644
--- a/examples/components/Form/Picker.jsx
+++ b/examples/components/Form/Picker.jsx
@@ -40,13 +40,13 @@ export default {
value: 4
}
],
- "onEvent": {
- "itemclick": {
- "actions": [
+ onEvent: {
+ itemclick: {
+ actions: [
{
- "actionType": "alert",
- "args": {
- "msg": "${event.data.label}~${event.data.id}"
+ actionType: 'alert',
+ args: {
+ msg: '${item.label}~${item.value}'
}
}
]
@@ -221,8 +221,7 @@ export default {
},
{
type: 'html',
- html:
- '添加其他 Html 片段 需要支持变量替换(todo).
'
+ html: '添加其他 Html 片段 需要支持变量替换(todo).
'
}
]
}
@@ -298,13 +297,13 @@ export default {
}
]
},
- "onEvent": {
- "itemclick": {
- "actions": [
+ onEvent: {
+ itemclick: {
+ actions: [
{
- "actionType": "alert",
- "args": {
- "msg": "${ecent.data.label}~${event.data.id}"
+ actionType: 'alert',
+ args: {
+ msg: '${item|json}'
}
}
]
@@ -446,8 +445,7 @@ export default {
},
{
type: 'html',
- html:
- '添加其他 Html 片段 需要支持变量替换(todo).
'
+ html: '添加其他 Html 片段 需要支持变量替换(todo).
'
}
]
}
@@ -622,8 +620,7 @@ export default {
},
{
type: 'html',
- html:
- '添加其他 Html 片段 需要支持变量替换(todo).
'
+ html: '添加其他 Html 片段 需要支持变量替换(todo).
'
}
]
}
@@ -813,8 +810,7 @@ export default {
},
{
type: 'html',
- html:
- '添加其他 Html 片段 需要支持变量替换(todo).
'
+ html: '添加其他 Html 片段 需要支持变量替换(todo).
'
}
]
}
@@ -1021,8 +1017,7 @@ export default {
},
{
type: 'html',
- html:
- '添加其他 Html 片段 需要支持变量替换(todo).
'
+ html: '添加其他 Html 片段 需要支持变量替换(todo).
'
}
]
}
@@ -1212,8 +1207,7 @@ export default {
},
{
type: 'html',
- html:
- '添加其他 Html 片段 需要支持变量替换(todo).
'
+ html: '添加其他 Html 片段 需要支持变量替换(todo).
'
}
]
}
diff --git a/packages/amis-core/src/actions/Action.ts b/packages/amis-core/src/actions/Action.ts
index 9b8469a67..17b9d8569 100644
--- a/packages/amis-core/src/actions/Action.ts
+++ b/packages/amis-core/src/actions/Action.ts
@@ -117,20 +117,15 @@ export const runAction = async (
) => {
// 用户可能,需要用到事件数据和当前域的数据,因此merge事件数据和当前渲染器数据
// 需要保持渲染器数据链完整
- const mergeData = renderer.props.data.__super
- ? createObject(
- createObject(renderer.props.data.__super, {
- event
- }),
- renderer.props.data
- )
- : createObject(
- {
- event
- },
- renderer.props.data
- );
-
+ const mergeData = createObject(
+ event.data,
+ renderer.props.data.__super
+ ? createObject(
+ renderer.props.data.__super,
+ createObject(renderer.props.data, {event})
+ )
+ : createObject(renderer.props.data, {event})
+ );
// 兼容一下1.9.0之前的版本
const expression = actionConfig.expression ?? actionConfig.execOn;
diff --git a/packages/amis-core/src/actions/Decorators.ts b/packages/amis-core/src/actions/Decorators.ts
deleted file mode 100644
index a45ef4efa..000000000
--- a/packages/amis-core/src/actions/Decorators.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-import {FormControlProps} from '../renderers/Item';
-import {createObject} from '../utils/helper';
-
-import type {RendererEvent} from '../utils/renderer-event';
-
-/**
- * 渲染器事件派发
- *
- * @param props 组件props
- * @param e 事件类型
- * @param ctx 上下文数据
- */
-export async function rendererEventDispatcher<
- T extends FormControlProps,
- E = any
->(
- props: T,
- e: E,
- ctx: Record = {}
-): Promise | undefined> {
- const {dispatchEvent, data} = props;
-
- return dispatchEvent(e, createObject(data, ctx));
-}
-
-/**
- * 渲染器事件方法装饰器
- *
- * @param event 事件类型
- * @param ctx 上下文数据
- * @returns {Function}
- */
-export function bindRendererEvent(
- event: E,
- ctx: Record = {},
- preventable = true
-) {
- return function (
- target: any,
- propertyKey: string,
- descriptor: TypedPropertyDescriptor
- ) {
- let fn =
- descriptor.value && typeof descriptor.value === 'function'
- ? descriptor.value
- : typeof descriptor?.get === 'function'
- ? descriptor.get()
- : null;
-
- if (!fn || typeof fn !== 'function') {
- throw new Error(
- `decorator can only be applied to methods not: ${typeof fn}`
- );
- }
-
- return {
- ...descriptor,
-
- value: async function boundFn(...params: any[]) {
- const triggerProps = (this as TypedPropertyDescriptor & {props: T})
- ?.props;
- let value = triggerProps?.value;
-
- // clear清除内容事件
- if (typeof event === 'string' && event === 'clear') {
- value = triggerProps?.resetValue;
- }
-
- if (preventable === false) {
- rendererEventDispatcher(triggerProps, event, {
- value
- });
- } else {
- const dispatcher = await rendererEventDispatcher(
- triggerProps,
- event,
- {
- value
- }
- );
-
- if (dispatcher?.prevented) {
- return;
- }
- }
-
- return fn.apply(this, [...params]);
- }
- };
- };
-}
diff --git a/packages/amis-core/src/actions/index.ts b/packages/amis-core/src/actions/index.ts
index 3ab693443..63c7b4d0f 100644
--- a/packages/amis-core/src/actions/index.ts
+++ b/packages/amis-core/src/actions/index.ts
@@ -18,7 +18,5 @@ import './EmailAction';
import './LinkAction';
import './ToastAction';
import './PageAction';
-import './Decorators';
-export * from './Decorators';
export * from './Action';
diff --git a/packages/amis-core/src/renderers/Options.tsx b/packages/amis-core/src/renderers/Options.tsx
index b16111783..bf2a8bcda 100644
--- a/packages/amis-core/src/renderers/Options.tsx
+++ b/packages/amis-core/src/renderers/Options.tsx
@@ -54,7 +54,8 @@ import isPlainObject from 'lodash/isPlainObject';
import {normalizeOptions} from '../utils/normalizeOptions';
import {optionValueCompare} from '../utils/optionValueCompare';
import {Option} from '../types';
-import {isEqual} from 'lodash';
+import isEqual from 'lodash/isEqual';
+import {resolveEventData} from '../utils';
export {Option};
@@ -475,13 +476,14 @@ export function registerOptionsControl(config: OptionsConfig) {
}
async dispatchOptionEvent(eventName: string, eventData: any = '') {
- const {dispatchEvent, options, data} = this.props;
+ const {dispatchEvent, options} = this.props;
const rendererEvent = await dispatchEvent(
eventName,
- createObject(data, {
- value: eventData,
- options
- })
+ resolveEventData(
+ this.props,
+ {value: eventData, options, items: options}, // 为了保持名字统一
+ 'value'
+ )
);
// 返回阻塞标识
return !!rendererEvent?.prevented;
diff --git a/packages/amis-core/src/utils/renderer-event.ts b/packages/amis-core/src/utils/renderer-event.ts
index e8dde790f..9d6ff0605 100644
--- a/packages/amis-core/src/utils/renderer-event.ts
+++ b/packages/amis-core/src/utils/renderer-event.ts
@@ -1,6 +1,7 @@
import {ListenerAction, ListenerContext, runActions} from '../actions/Action';
import {RendererProps} from '../factory';
import {IScopedContext} from '../Scoped';
+import {createObject} from './object';
// 事件监听器
export interface EventListeners {
@@ -181,4 +182,22 @@ export const getRendererEventListeners = () => {
return rendererEventListeners;
};
+/**
+ * 兼容历史配置,追加对应name的值
+ * @param props
+ * @param data
+ * @param valueKey
+ */
+export const resolveEventData = (props: any, data: any, valueKey?: string) => {
+ return createObject(
+ props.data,
+ props.name && valueKey
+ ? {
+ ...data,
+ [props.name]: data[valueKey]
+ }
+ : data
+ );
+};
+
export default {};
diff --git a/packages/amis-ui/src/components/Textarea.tsx b/packages/amis-ui/src/components/Textarea.tsx
index b4ffcf92c..655113b00 100644
--- a/packages/amis-ui/src/components/Textarea.tsx
+++ b/packages/amis-ui/src/components/Textarea.tsx
@@ -142,9 +142,10 @@ export class Textarea extends React.Component {
focused: false
},
() => {
- if (trimContents && value && typeof value === 'string') {
- onChange?.(value.trim());
- }
+ // 和renderer的重复了,不知道这里干啥的,先注释了
+ // if (trimContents && value && typeof value === 'string') {
+ // onChange?.(value.trim());
+ // }
onBlur && onBlur(e);
}
diff --git a/packages/amis/__tests__/event-action/renderers/form/__snapshots__/range.test.tsx.snap b/packages/amis/__tests__/event-action/renderers/form/__snapshots__/range.test.tsx.snap
index e659ffcfb..e2c14c458 100644
--- a/packages/amis/__tests__/event-action/renderers/form/__snapshots__/range.test.tsx.snap
+++ b/packages/amis/__tests__/event-action/renderers/form/__snapshots__/range.test.tsx.snap
@@ -333,7 +333,7 @@ exports[`EventAction:inputRange 1`] = `
style="cursor: default;"
>
"
- 值改变为0了
+ 值为0
"
@@ -435,7 +435,7 @@ exports[`EventAction:inputRange 1`] = `
placeholder=""
size="10"
type="text"
- value="值改变为0了"
+ value="值为0"
/>
diff --git a/packages/amis/__tests__/event-action/renderers/form/range.test.tsx b/packages/amis/__tests__/event-action/renderers/form/range.test.tsx
index cbc1eeafd..0abaae52e 100644
--- a/packages/amis/__tests__/event-action/renderers/form/range.test.tsx
+++ b/packages/amis/__tests__/event-action/renderers/form/range.test.tsx
@@ -24,7 +24,8 @@ test('EventAction:inputRange', async () => {
componentId: 'form_data',
args: {
value: {
- rangeValue: '值改变为${event.data.value}了'
+ rangeEvent: '触发了change',
+ rangeValue: '值为${range}'
}
}
}
@@ -37,7 +38,8 @@ test('EventAction:inputRange', async () => {
componentId: 'form_data',
args: {
value: {
- rangeEvent: '触发了blur'
+ rangeEvent: '触发了blur',
+ rangeValue: '值为${range}'
}
}
}
@@ -50,7 +52,8 @@ test('EventAction:inputRange', async () => {
componentId: 'form_data',
args: {
value: {
- rangeEvent: '触发了focus'
+ rangeEvent: '触发了focus',
+ rangeValue: '值为${range}'
}
}
}
@@ -105,7 +108,10 @@ test('EventAction:inputRange', async () => {
await wait(300);
await waitFor(() => {
expect(
- container.querySelector(`[value="值改变为${valueChange}了"]`)
+ container.querySelector('[value="触发了change"]')
+ ).toBeInTheDocument();
+ expect(
+ container.querySelector(`[value="值为${valueChange}"]`)
).toBeInTheDocument();
});
@@ -120,8 +126,9 @@ test('EventAction:inputRange', async () => {
await wait(300);
await waitFor(() => {
expect(
- container.querySelector(`[value="值改变为0了"]`)
+ container.querySelector('[value="触发了change"]')
).toBeInTheDocument();
+ expect(container.querySelector(`[value="值为0"]`)).toBeInTheDocument();
});
// focus
@@ -131,6 +138,7 @@ test('EventAction:inputRange', async () => {
expect(
container.querySelector('[value="触发了focus"]')
).toBeInTheDocument();
+ expect(container.querySelector(`[value="值为0"]`)).toBeInTheDocument();
});
// blur
@@ -138,6 +146,7 @@ test('EventAction:inputRange', async () => {
await wait(300);
await waitFor(() => {
expect(container.querySelector('[value="触发了blur"]')).toBeInTheDocument();
+ expect(container.querySelector(`[value="值为0"]`)).toBeInTheDocument();
});
expect(container).toMatchSnapshot();
diff --git a/packages/amis/src/renderers/Dialog.tsx b/packages/amis/src/renderers/Dialog.tsx
index 96b88faae..79266a6e0 100644
--- a/packages/amis/src/renderers/Dialog.tsx
+++ b/packages/amis/src/renderers/Dialog.tsx
@@ -786,7 +786,8 @@ export class DialogRenderer extends Dialog {
throwErrors: boolean = false,
delegate?: IScopedContext
) {
- const {onAction, store, onConfirm, env, dispatchEvent} = this.props;
+ const {onAction, store, onConfirm, env, dispatchEvent, onClose} =
+ this.props;
if (action.from === this.$$id) {
return onAction
? onAction(e, action, data, throwErrors, delegate || this.context)
@@ -809,8 +810,11 @@ export class DialogRenderer extends Dialog {
if (rendererEvent?.prevented) {
return;
}
+
store.setCurrentAction(action);
- this.handleSelfClose();
+ // clear error
+ store.updateMessage();
+ onClose();
action.close && this.closeTarget(action.close);
} else if (action.actionType === 'confirm') {
const rendererEvent = await dispatchEvent(
@@ -820,15 +824,22 @@ export class DialogRenderer extends Dialog {
if (rendererEvent?.prevented) {
return;
}
+
store.setCurrentAction(action);
- this.tryChildrenToHandle(
+ const handleResult = this.tryChildrenToHandle(
{
...action,
actionType: 'submit'
},
data,
action
- ) || this.handleSelfClose(undefined, true);
+ );
+
+ if (!handleResult) {
+ // clear error
+ store.updateMessage();
+ onClose(true);
+ }
} else if (action.actionType === 'next' || action.actionType === 'prev') {
store.setCurrentAction(action);
if (action.type === 'submit') {
diff --git a/packages/amis/src/renderers/DropDownButton.tsx b/packages/amis/src/renderers/DropDownButton.tsx
index 4f678ebc4..7ef09f699 100644
--- a/packages/amis/src/renderers/DropDownButton.tsx
+++ b/packages/amis/src/renderers/DropDownButton.tsx
@@ -180,7 +180,9 @@ export default class DropDownButton extends React.Component<
}
async open() {
- await this.props.dispatchEvent('mouseenter', {data: this.props.buttons});
+ await this.props.dispatchEvent('mouseenter', {
+ items: this.props.buttons // 为了保持名字统一
+ });
this.setState({
isOpened: true
});
@@ -188,7 +190,7 @@ export default class DropDownButton extends React.Component<
close() {
this.timer = setTimeout(() => {
- this.props.dispatchEvent('mouseleave', {data: this.props.buttons});
+ this.props.dispatchEvent('mouseleave', {items: this.props.buttons});
this.setState({
isOpened: false
});
@@ -378,13 +380,17 @@ export default class DropDownButton extends React.Component<
size ? `Button--${size}` : ''
)}
>
- {hasIcon(icon)
- ?
- : generateIcon(cx, icon, 'm-r-xs')}
+ {hasIcon(icon) ? (
+
+ ) : (
+ generateIcon(cx, icon, 'm-r-xs')
+ )}
{typeof label === 'string' ? filter(label, data) : label}
- {rightIcon && hasIcon(rightIcon)
- ?
- : generateIcon(cx, rightIcon, 'm-l-xs')}
+ {rightIcon && hasIcon(rightIcon) ? (
+
+ ) : (
+ generateIcon(cx, rightIcon, 'm-l-xs')
+ )}
{!hideCaret ? (
diff --git a/packages/amis/src/renderers/Form/ChainedSelect.tsx b/packages/amis/src/renderers/Form/ChainedSelect.tsx
index da88a79ab..09242fff8 100644
--- a/packages/amis/src/renderers/Form/ChainedSelect.tsx
+++ b/packages/amis/src/renderers/Form/ChainedSelect.tsx
@@ -4,7 +4,8 @@ import {
OptionsControl,
OptionsControlProps,
Option,
- FormOptionsControl
+ FormOptionsControl,
+ resolveEventData
} from 'amis-core';
import {Select} from 'amis-ui';
import {Api} from 'amis-core';
@@ -184,9 +185,7 @@ export default class ChainedSelectControl extends React.Component<
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value: valueRes
- })
+ resolveEventData(this.props, {value: valueRes}, 'value')
);
if (rendererEvent?.prevented) {
@@ -240,9 +239,7 @@ export default class ChainedSelectControl extends React.Component<
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value: valueRes
- })
+ resolveEventData(this.props, {value: valueRes}, 'value')
);
if (rendererEvent?.prevented) {
diff --git a/packages/amis/src/renderers/Form/Checkbox.tsx b/packages/amis/src/renderers/Form/Checkbox.tsx
index 2be7faa85..79fc86dfe 100644
--- a/packages/amis/src/renderers/Form/Checkbox.tsx
+++ b/packages/amis/src/renderers/Form/Checkbox.tsx
@@ -1,5 +1,10 @@
import React from 'react';
-import {FormItem, FormControlProps, FormBaseControl} from 'amis-core';
+import {
+ FormItem,
+ FormControlProps,
+ FormBaseControl,
+ resolveEventData
+} from 'amis-core';
import cx from 'classnames';
import {Checkbox} from 'amis-ui';
import {withBadge, BadgeObject} from 'amis-ui';
@@ -74,12 +79,10 @@ export default class CheckboxControl extends React.Component<
@autobind
async dispatchChangeEvent(eventData: any = {}) {
- const {dispatchEvent, data, onChange} = this.props;
+ const {dispatchEvent, onChange} = this.props;
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value: eventData
- })
+ resolveEventData(this.props, {value: eventData}, 'value')
);
if (rendererEvent?.prevented) {
diff --git a/packages/amis/src/renderers/Form/Combo.tsx b/packages/amis/src/renderers/Form/Combo.tsx
index b2dad9cb2..45416dba0 100644
--- a/packages/amis/src/renderers/Form/Combo.tsx
+++ b/packages/amis/src/renderers/Form/Combo.tsx
@@ -1,7 +1,12 @@
import React from 'react';
import {findDOMNode} from 'react-dom';
import cloneDeep from 'lodash/cloneDeep';
-import {FormItem, FormControlProps, FormBaseControl} from 'amis-core';
+import {
+ FormItem,
+ FormControlProps,
+ FormBaseControl,
+ resolveEventData
+} from 'amis-core';
import {ActionObject, Api} from 'amis-core';
import {ComboStore, IComboStore} from 'amis-core';
import {Tabs as CTabs, Tab, Button} from 'amis-ui';
@@ -509,7 +514,6 @@ export default class ComboControl extends React.Component {
scaffold,
disabled,
submitOnChange,
- data,
dispatchEvent
} = this.props;
@@ -519,12 +523,17 @@ export default class ComboControl extends React.Component {
let value = this.getValueAsArray();
+ // todo:这里的数据结构与表单项最终类型不一致,需要区分是否多选、是否未input-kv or input-kvs
const rendererEvent = await dispatchEvent(
'add',
- createObject(data, {
- value:
- flat && joinValues ? value.join(delimiter || ',') : cloneDeep(value)
- })
+ resolveEventData(
+ this.props,
+ {
+ value:
+ flat && joinValues ? value.join(delimiter || ',') : cloneDeep(value)
+ },
+ 'value'
+ )
);
if (rendererEvent?.prevented) {
@@ -572,13 +581,21 @@ export default class ComboControl extends React.Component {
let value = this.getValueAsArray();
const ctx = createObject(data, value[key]);
+ // todo:这里的数据结构与表单项最终类型不一致,需要区分是否多选、是否未input-kv or input-kvs
const rendererEvent = await dispatchEvent(
'delete',
- createObject(data, {
- key,
- value:
- flat && joinValues ? value.join(delimiter || ',') : cloneDeep(value)
- })
+ resolveEventData(
+ this.props,
+ {
+ key,
+ value:
+ flat && joinValues
+ ? value.join(delimiter || ',')
+ : cloneDeep(value),
+ item: value[key]
+ },
+ 'value'
+ )
);
if (rendererEvent?.prevented) {
@@ -969,13 +986,22 @@ export default class ComboControl extends React.Component {
@autobind
async handleTabSelect(key: number) {
- const {store, data, dispatchEvent} = this.props;
-
+ const {store, data, name, value, dispatchEvent} = this.props;
+ const eventData = {
+ key,
+ item: value[key]
+ };
const rendererEvent = await dispatchEvent(
'tabsChange',
- createObject(data, {
- key
- })
+ createObject(
+ data,
+ name
+ ? {
+ ...eventData,
+ [name]: value
+ }
+ : eventData
+ )
);
if (rendererEvent?.prevented) {
diff --git a/packages/amis/src/renderers/Form/DiffEditor.tsx b/packages/amis/src/renderers/Form/DiffEditor.tsx
index 93a504583..8b57063cb 100644
--- a/packages/amis/src/renderers/Form/DiffEditor.tsx
+++ b/packages/amis/src/renderers/Form/DiffEditor.tsx
@@ -1,10 +1,14 @@
import React from 'react';
-import {FormItem, FormControlProps, FormBaseControl} from 'amis-core';
+import {
+ FormItem,
+ FormControlProps,
+ FormBaseControl,
+ resolveEventData
+} from 'amis-core';
import {LazyComponent} from 'amis-core';
import {isPureVariable, resolveVariableAndFilter} from 'amis-core';
import {FormBaseControlSchema, SchemaTokenizeableString} from '../../Schema';
import {autobind} from 'amis-core';
-import {bindRendererEvent} from 'amis-core';
import type {Position} from 'monaco-editor';
import type {ListenerAction} from 'amis-core';
@@ -130,18 +134,42 @@ export class DiffEditor extends React.Component {
this.editor?.setPosition(position);
}
- @bindRendererEvent('focus')
- handleFocus() {
+ async handleFocus(e: any) {
+ const {dispatchEvent, value, onFocus} = this.props;
+
this.setState({
focused: true
});
+
+ const rendererEvent = await dispatchEvent(
+ 'focus',
+ resolveEventData(this.props, {value}, 'value')
+ );
+
+ if (rendererEvent?.prevented) {
+ return;
+ }
+
+ onFocus?.(e);
}
- @bindRendererEvent('blur')
- handleBlur() {
+ async handleBlur(e: any) {
+ const {dispatchEvent, value, onBlur} = this.props;
+
this.setState({
focused: false
});
+
+ const rendererEvent = await dispatchEvent(
+ 'blur',
+ resolveEventData(this.props, {value}, 'value')
+ );
+
+ if (rendererEvent?.prevented) {
+ return;
+ }
+
+ onBlur?.(e);
}
componentDidUpdate(prevProps: any) {
@@ -225,9 +253,20 @@ export class DiffEditor extends React.Component {
});
}
- handleModifiedEditorChange() {
- const {onChange} = this.props;
- onChange && onChange(this.modifiedEditor.getModel().getValue());
+ async handleModifiedEditorChange() {
+ const {onChange, dispatchEvent} = this.props;
+ const value = this.modifiedEditor.getModel().getValue();
+
+ const rendererEvent = await dispatchEvent(
+ 'change',
+ resolveEventData(this.props, {value}, 'value')
+ );
+
+ if (rendererEvent?.prevented) {
+ return;
+ }
+
+ onChange && onChange(value);
}
prevHeight = 0;
diff --git a/packages/amis/src/renderers/Form/Editor.tsx b/packages/amis/src/renderers/Form/Editor.tsx
index 57bfe32fc..5e329f756 100644
--- a/packages/amis/src/renderers/Form/Editor.tsx
+++ b/packages/amis/src/renderers/Form/Editor.tsx
@@ -1,10 +1,14 @@
import React from 'react';
-import {FormItem, FormControlProps, FormBaseControl} from 'amis-core';
+import {
+ FormItem,
+ FormControlProps,
+ FormBaseControl,
+ resolveEventData
+} from 'amis-core';
import {LazyComponent} from 'amis-core';
import {Editor} from 'amis-ui';
import {autobind} from 'amis-core';
import {isPureVariable, resolveVariableAndFilter} from 'amis-core';
-import {bindRendererEvent} from 'amis-core';
import type {Position} from 'monaco-editor';
import type {ListenerAction} from 'amis-core';
@@ -148,6 +152,7 @@ export default class EditorControl extends React.Component {
this.handleFocus = this.handleFocus.bind(this);
this.handleBlur = this.handleBlur.bind(this);
+ this.handleChange = this.handleChange.bind(this);
this.handleEditorMounted = this.handleEditorMounted.bind(this);
}
@@ -177,18 +182,56 @@ export default class EditorControl extends React.Component {
this.editor?.setPosition(position);
}
- @bindRendererEvent('focus')
- handleFocus() {
+ async handleFocus(e: any) {
+ const {dispatchEvent, value, onFocus} = this.props;
+
this.setState({
focused: true
});
+
+ const rendererEvent = await dispatchEvent(
+ 'focus',
+ resolveEventData(this.props, {value}, 'value')
+ );
+
+ if (rendererEvent?.prevented) {
+ return;
+ }
+
+ onFocus?.(e);
}
- @bindRendererEvent('blur')
- handleBlur() {
+ async handleBlur(e: any) {
+ const {dispatchEvent, value, onBlur} = this.props;
+
this.setState({
focused: false
});
+
+ const rendererEvent = await dispatchEvent(
+ 'blur',
+ resolveEventData(this.props, {value}, 'value')
+ );
+
+ if (rendererEvent?.prevented) {
+ return;
+ }
+
+ onBlur?.(e);
+ }
+
+ async handleChange(e: any) {
+ const {dispatchEvent, onChange} = this.props;
+
+ const rendererEvent = await dispatchEvent(
+ 'change',
+ resolveEventData(this.props, {value: e}, 'value')
+ );
+
+ if (rendererEvent?.prevented) {
+ return;
+ }
+ onChange?.(e);
}
handleEditorMounted(editor: any, monaco: any) {
@@ -276,7 +319,7 @@ export default class EditorControl extends React.Component {
component={Editor}
allowFullscreen={allowFullscreen}
value={finnalValue}
- onChange={onChange}
+ onChange={this.handleChange}
disabled={disabled}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
diff --git a/packages/amis/src/renderers/Form/InputCity.tsx b/packages/amis/src/renderers/Form/InputCity.tsx
index 0b249fac1..ed350de25 100644
--- a/packages/amis/src/renderers/Form/InputCity.tsx
+++ b/packages/amis/src/renderers/Form/InputCity.tsx
@@ -1,5 +1,10 @@
import React from 'react';
-import {FormItem, FormControlProps, FormBaseControl} from 'amis-core';
+import {
+ FormItem,
+ FormControlProps,
+ FormBaseControl,
+ resolveEventData
+} from 'amis-core';
import {ClassNamesFn, themeable, ThemeProps} from 'amis-core';
import {Spinner} from 'amis-ui';
import {Select} from 'amis-ui';
@@ -476,13 +481,11 @@ export class LocationControl extends React.Component {
@autobind
async handleChange(value: number | string) {
- const {dispatchEvent, data, onChange} = this.props;
+ const {dispatchEvent, onChange} = this.props;
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value
- })
+ resolveEventData(this.props, {value}, 'value')
);
if (rendererEvent?.prevented) {
diff --git a/packages/amis/src/renderers/Form/InputDate.tsx b/packages/amis/src/renderers/Form/InputDate.tsx
index 8a129f20a..71a4b8808 100644
--- a/packages/amis/src/renderers/Form/InputDate.tsx
+++ b/packages/amis/src/renderers/Form/InputDate.tsx
@@ -1,5 +1,10 @@
import React from 'react';
-import {FormItem, FormControlProps, FormBaseControl} from 'amis-core';
+import {
+ FormItem,
+ FormControlProps,
+ FormBaseControl,
+ resolveEventData
+} from 'amis-core';
import cx from 'classnames';
import {filterDate, isPureVariable, resolveVariableAndFilter} from 'amis-core';
import moment from 'moment';
@@ -423,8 +428,8 @@ export default class DateControl extends React.PureComponent<
// 派发有event的事件
@autobind
dispatchEvent(e: React.SyntheticEvent) {
- const {dispatchEvent, data, value} = this.props;
- dispatchEvent(e, createObject(data, {value}));
+ const {dispatchEvent, value} = this.props;
+ dispatchEvent(e, resolveEventData(this.props, {value}, 'value'));
}
// 动作
@@ -444,10 +449,10 @@ export default class DateControl extends React.PureComponent<
// 值的变化
@autobind
async handleChange(nextValue: any) {
- const {dispatchEvent, data} = this.props;
+ const {dispatchEvent} = this.props;
const dispatcher = dispatchEvent(
'change',
- createObject(data, {value: nextValue})
+ resolveEventData(this.props, {value: nextValue}, 'value')
);
if (dispatcher?.prevented) {
return;
diff --git a/packages/amis/src/renderers/Form/InputDateRange.tsx b/packages/amis/src/renderers/Form/InputDateRange.tsx
index 76ac91329..629309f68 100644
--- a/packages/amis/src/renderers/Form/InputDateRange.tsx
+++ b/packages/amis/src/renderers/Form/InputDateRange.tsx
@@ -1,5 +1,10 @@
import React from 'react';
-import {FormItem, FormControlProps, FormBaseControl} from 'amis-core';
+import {
+ FormItem,
+ FormControlProps,
+ FormBaseControl,
+ resolveEventData
+} from 'amis-core';
import cx from 'classnames';
import {filterDate, parseDuration} from 'amis-core';
import 'moment/locale/zh-cn';
@@ -196,12 +201,7 @@ export default class DateRangeControl extends React.Component {
dispatchEvent(eventName: string) {
const {dispatchEvent, data, value} = this.props;
- dispatchEvent(
- eventName,
- createObject(data, {
- value
- })
- );
+ dispatchEvent(eventName, resolveEventData(this.props, {value}, 'value'));
}
// 动作
@@ -224,7 +224,7 @@ export default class DateRangeControl extends React.Component {
const {dispatchEvent, data} = this.props;
const dispatcher = dispatchEvent(
'change',
- createObject(data, {value: nextValue})
+ resolveEventData(this.props, {value: nextValue}, 'value')
);
if (dispatcher?.prevented) {
return;
diff --git a/packages/amis/src/renderers/Form/InputExcel.tsx b/packages/amis/src/renderers/Form/InputExcel.tsx
index c442bb679..b89fb910d 100644
--- a/packages/amis/src/renderers/Form/InputExcel.tsx
+++ b/packages/amis/src/renderers/Form/InputExcel.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import Dropzone from 'react-dropzone';
-import {autobind, createObject, isObject} from 'amis-core';
-import {FormItem, FormControlProps} from 'amis-core';
+import {autobind, createObject, isObject, resolveEventData} from 'amis-core';
+import {FormItem, FormControlProps, FormBaseControl} from 'amis-core';
import {FormBaseControlSchema} from '../../Schema';
import type {CellValue, CellRichTextValue} from 'exceljs';
@@ -74,7 +74,7 @@ export default class ExcelControl extends React.PureComponent<
@autobind
handleDrop(files: File[]) {
- const {allSheets, onChange, dispatchEvent, data} = this.props;
+ const {allSheets, onChange, dispatchEvent} = this.props;
const excel = files[0];
const reader = new FileReader();
reader.readAsArrayBuffer(excel);
@@ -111,9 +111,7 @@ export default class ExcelControl extends React.PureComponent<
const {dispatchEvent, data} = this.props;
return await dispatchEvent(
eventName,
- createObject(data, {
- value: eventData
- })
+ resolveEventData(this.props, {value: eventData}, 'value')
);
}
diff --git a/packages/amis/src/renderers/Form/InputFile.tsx b/packages/amis/src/renderers/Form/InputFile.tsx
index ddf5919b4..805d1e4e0 100644
--- a/packages/amis/src/renderers/Form/InputFile.tsx
+++ b/packages/amis/src/renderers/Form/InputFile.tsx
@@ -1,5 +1,10 @@
import React from 'react';
-import {FormItem, FormControlProps, prettyBytes} from 'amis-core';
+import {
+ FormItem,
+ FormControlProps,
+ prettyBytes,
+ resolveEventData
+} from 'amis-core';
import find from 'lodash/find';
import isPlainObject from 'lodash/isPlainObject';
import {Payload, ApiObject, ApiString, ActionObject} from 'amis-core';
@@ -844,9 +849,9 @@ export default class FileControl extends React.Component {
(ret.data as any).value || (ret.data as any).url || ret.data;
const dispatcher = await this.dispatchEvent('success', {
- ...file,
- value,
- state: 'uploaded'
+ ...file, // 保留历史结构
+ item: file,
+ value
});
if (dispatcher?.prevented) {
return;
@@ -859,7 +864,10 @@ export default class FileControl extends React.Component {
});
})
.catch(async error => {
- const dispatcher = await this.dispatchEvent('fail', {file, error});
+ const dispatcher = await this.dispatchEvent('fail', {
+ item: file,
+ error
+ });
if (dispatcher?.prevented) {
return;
}
@@ -871,7 +879,10 @@ export default class FileControl extends React.Component {
const files = this.state.files.concat();
const removeFile = files[index];
// 触发移出文件事件
- const dispatcher = await this.dispatchEvent('remove', removeFile);
+ const dispatcher = await this.dispatchEvent('remove', {
+ ...removeFile, // 保留历史结构
+ item: removeFile
+ });
if (dispatcher?.prevented) {
return;
}
@@ -1279,21 +1290,27 @@ export default class FileControl extends React.Component {
}
async dispatchEvent(e: string, data?: Record) {
- const {dispatchEvent} = this.props;
+ const {dispatchEvent, multiple} = this.props;
const getEventData = (item: Record) => ({
name: item.path || item.name,
value: item.value,
state: item.state,
error: item.error
});
- const value = data
+ const value: any = data
? getEventData(data)
: this.state.files.map(item => getEventData(item));
+
return dispatchEvent(
e,
- createObject(this.props.data, {
- file: value
- })
+ resolveEventData(
+ this.props,
+ {
+ ...data,
+ file: multiple ? value : value?.[0]
+ },
+ 'file'
+ )
);
}
diff --git a/packages/amis/src/renderers/Form/InputImage.tsx b/packages/amis/src/renderers/Form/InputImage.tsx
index a5d8b86a4..ae1de544e 100644
--- a/packages/amis/src/renderers/Form/InputImage.tsx
+++ b/packages/amis/src/renderers/Form/InputImage.tsx
@@ -3,7 +3,8 @@ import {
FormItem,
FormControlProps,
FormBaseControl,
- prettyBytes
+ prettyBytes,
+ resolveEventData
} from 'amis-core';
// import 'cropperjs/dist/cropper.css';
const Cropper = React.lazy(() => import('react-cropper'));
@@ -729,7 +730,10 @@ export default class ImageControl extends React.Component<
async removeFile(file: FileValue, index: number) {
const files = this.files.concat();
- const dispatcher = await this.dispatchEvent('remove', file);
+ const dispatcher = await this.dispatchEvent('remove', {
+ ...file, // 保留历史结构
+ item: file
+ });
if (dispatcher?.prevented) {
return;
}
@@ -1083,7 +1087,10 @@ export default class ImageControl extends React.Component<
if (error) {
file.state = 'invalid';
- const dispatcher = await this.dispatchEvent('fail', {file, error});
+ const dispatcher = await this.dispatchEvent('fail', {
+ item: file,
+ error
+ });
if (dispatcher?.prevented) {
return;
}
@@ -1114,9 +1121,9 @@ export default class ImageControl extends React.Component<
obj.value = obj.value || obj.url;
const dispatcher = await this.dispatchEvent('success', {
- ...file,
- value: obj.value,
- state: 'uploaded'
+ ...file, // 保留历史结构
+ item: file,
+ value: obj.value
});
if (dispatcher?.prevented) {
return;
@@ -1125,7 +1132,7 @@ export default class ImageControl extends React.Component<
})
.catch(async error => {
const dispatcher = await this.dispatchEvent('fail', {
- file,
+ item: file,
error
});
if (dispatcher?.prevented) {
@@ -1287,17 +1294,24 @@ export default class ImageControl extends React.Component<
}
async dispatchEvent(e: string, data?: Record) {
- const {dispatchEvent} = this.props;
+ const {dispatchEvent, multiple} = this.props;
const getEventData = (item: Record) => ({
name: item.path || item.name,
value: item.value,
state: item.state,
error: item.error
});
- const value = data
+ const value: any = data
? getEventData(data)
: this.files.map(item => getEventData(item));
- return dispatchEvent(e, createObject(this.props.data, {file: value}));
+ return dispatchEvent(
+ e,
+ resolveEventData(
+ this.props,
+ {...data, file: multiple ? value : value?.[0]},
+ 'file'
+ )
+ );
}
// 动作
diff --git a/packages/amis/src/renderers/Form/InputNumber.tsx b/packages/amis/src/renderers/Form/InputNumber.tsx
index 45e4a2491..df8086b47 100644
--- a/packages/amis/src/renderers/Form/InputNumber.tsx
+++ b/packages/amis/src/renderers/Form/InputNumber.tsx
@@ -1,6 +1,11 @@
import React from 'react';
import {toFixed} from 'rc-input-number/lib/utils/MiniDecimal';
-import {FormItem, FormControlProps} from 'amis-core';
+import {
+ FormItem,
+ FormControlProps,
+ FormBaseControl,
+ resolveEventData
+} from 'amis-core';
import cx from 'classnames';
import {NumberInput, Select} from 'amis-ui';
import {
@@ -242,25 +247,18 @@ export default class NumberControl extends React.Component<
// 派发有event的事件
@autobind
async dispatchEvent(eventName: string) {
- const {dispatchEvent, data, value} = this.props;
+ const {dispatchEvent, value} = this.props;
- dispatchEvent(
- eventName,
- createObject(data, {
- value
- })
- );
+ dispatchEvent(eventName, resolveEventData(this.props, {value}, 'value'));
}
async handleChange(inputValue: any) {
- const {onChange, data, dispatchEvent} = this.props;
+ const {onChange, dispatchEvent} = this.props;
const value = this.getValue(inputValue);
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value
- })
+ resolveEventData(this.props, {value}, 'value')
);
if (rendererEvent?.prevented) {
return;
diff --git a/packages/amis/src/renderers/Form/InputRange.tsx b/packages/amis/src/renderers/Form/InputRange.tsx
index fa59637ce..5c8f15d64 100644
--- a/packages/amis/src/renderers/Form/InputRange.tsx
+++ b/packages/amis/src/renderers/Form/InputRange.tsx
@@ -13,6 +13,7 @@ import {autobind, createObject} from 'amis-core';
import {filter} from 'amis-core';
import {FormBaseControlSchema, SchemaObject} from '../../Schema';
import {ActionObject} from 'amis-core';
+import {resolveEventData} from 'amis-core';
/**
* Range
@@ -384,30 +385,50 @@ export class Input extends React.Component {
* 失焦事件
*/
@autobind
- onBlur() {
- const {data, dispatchEvent, value} = this.props;
+ async onBlur(e: any) {
+ const {dispatchEvent, value, onBlur} = this.props;
- dispatchEvent(
+ const rendererEvent = await dispatchEvent(
'blur',
- createObject(data, {
- value
- })
+ resolveEventData(
+ this.props,
+ {
+ value
+ },
+ 'value'
+ )
);
+
+ if (rendererEvent?.prevented) {
+ return;
+ }
+
+ onBlur?.(e);
}
/**
* 聚焦事件
*/
@autobind
- async onFocus() {
- const {data, dispatchEvent, value} = this.props;
+ async onFocus(e: any) {
+ const {dispatchEvent, value, onFocus} = this.props;
- dispatchEvent(
+ const rendererEvent = await dispatchEvent(
'focus',
- createObject(data, {
- value
- })
+ resolveEventData(
+ this.props,
+ {
+ value
+ },
+ 'value'
+ )
);
+
+ if (rendererEvent?.prevented) {
+ return;
+ }
+
+ onFocus?.(e);
}
render() {
@@ -553,14 +574,18 @@ export default class RangeControl extends React.PureComponent<
@autobind
async onChange(value: FormatValue) {
this.setState({value: this.getValue(value)});
- const {onChange, data, dispatchEvent} = this.props;
+ const {onChange, dispatchEvent} = this.props;
const result = this.getFormatValue(value);
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value: result
- })
+ resolveEventData(
+ this.props,
+ {
+ value: result
+ },
+ 'value'
+ )
);
if (rendererEvent?.prevented) {
@@ -576,7 +601,7 @@ export default class RangeControl extends React.PureComponent<
@autobind
onAfterChange() {
const {value} = this.state;
- const {onAfterChange, dispatchEvent, data} = this.props;
+ const {onAfterChange} = this.props;
const result = this.getFormatValue(value);
onAfterChange && onAfterChange(result);
}
diff --git a/packages/amis/src/renderers/Form/InputRating.tsx b/packages/amis/src/renderers/Form/InputRating.tsx
index 973436762..d8a9867da 100644
--- a/packages/amis/src/renderers/Form/InputRating.tsx
+++ b/packages/amis/src/renderers/Form/InputRating.tsx
@@ -1,5 +1,10 @@
import React from 'react';
-import {FormItem, FormControlProps, FormBaseControl} from 'amis-core';
+import {
+ FormItem,
+ FormControlProps,
+ FormBaseControl,
+ resolveEventData
+} from 'amis-core';
import {autobind, createObject} from 'amis-core';
import {ActionObject} from 'amis-core';
import {Rating} from 'amis-ui';
@@ -101,13 +106,11 @@ export default class RatingControl extends React.Component {
@autobind
async handleChange(value: any) {
- const {onChange, dispatchEvent, data} = this.props;
+ const {onChange, dispatchEvent} = this.props;
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value
- })
+ resolveEventData(this.props, {value}, 'value')
);
if (rendererEvent?.prevented) {
diff --git a/packages/amis/src/renderers/Form/InputTag.tsx b/packages/amis/src/renderers/Form/InputTag.tsx
index e376b4810..42c24a9c5 100644
--- a/packages/amis/src/renderers/Form/InputTag.tsx
+++ b/packages/amis/src/renderers/Form/InputTag.tsx
@@ -3,7 +3,8 @@ import {
OptionsControl,
OptionsControlProps,
Option,
- FormOptionsControl
+ FormOptionsControl,
+ resolveEventData
} from 'amis-core';
import Downshift from 'downshift';
import find from 'lodash/find';
@@ -144,13 +145,18 @@ export default class TagControl extends React.PureComponent<
@autobind
async dispatchEvent(eventName: string, eventData: any = {}) {
- const {dispatchEvent, options, data} = this.props;
+ const {dispatchEvent, options} = this.props;
const rendererEvent = await dispatchEvent(
eventName,
- createObject(data, {
- options,
- ...eventData
- })
+ resolveEventData(
+ this.props,
+ {
+ options,
+ items: options, // 为了保持名字统一
+ ...eventData
+ },
+ 'value'
+ )
);
// 返回阻塞标识
return !!rendererEvent?.prevented;
@@ -523,7 +529,7 @@ export default class TagControl extends React.PureComponent<
disabled: reachMax || item.disabled,
className: cx('ListMenu-item', {
'is-disabled': reachMax
- }),
+ })
})
})}
/>
diff --git a/packages/amis/src/renderers/Form/InputText.tsx b/packages/amis/src/renderers/Form/InputText.tsx
index 54552d2b4..ee5074259 100644
--- a/packages/amis/src/renderers/Form/InputText.tsx
+++ b/packages/amis/src/renderers/Form/InputText.tsx
@@ -3,7 +3,8 @@ import {
OptionsControl,
OptionsControlProps,
highlight,
- FormOptionsControl
+ FormOptionsControl,
+ resolveEventData
} from 'amis-core';
import {ActionObject} from 'amis-core';
import Downshift, {StateChangeOptions} from 'downshift';
@@ -19,7 +20,6 @@ import {Spinner} from 'amis-ui';
import {ActionSchema} from '../Action';
import {FormOptionsSchema, SchemaApi} from '../../Schema';
import {generateIcon} from 'amis-core';
-import {rendererEventDispatcher, bindRendererEvent} from 'amis-core';
import type {Option} from 'amis-core';
import type {ListenerAction} from 'amis-core';
@@ -300,8 +300,22 @@ export default class TextControl extends React.PureComponent<
onChange(this.normalizeValue(newValue));
}
- @bindRendererEvent('click')
- handleClick() {
+ async handleClick() {
+ const {dispatchEvent, value} = this.props;
+ const rendererEvent = await dispatchEvent(
+ 'click',
+ resolveEventData(
+ this.props,
+ {
+ value
+ },
+ 'value'
+ )
+ );
+
+ if (rendererEvent?.prevented) {
+ return;
+ }
// 已经 focus 的就不重复执行,否则总重新定位光标
this.state.isFocused || this.focus();
this.setState({
@@ -309,19 +323,33 @@ export default class TextControl extends React.PureComponent<
});
}
- @bindRendererEvent('focus')
- handleFocus(e: any) {
+ async handleFocus(e: any) {
+ const {dispatchEvent, onFocus, value} = this.props;
this.setState({
isOpen: true,
isFocused: true
});
- this.props.onFocus && this.props.onFocus(e);
+ const rendererEvent = await dispatchEvent(
+ 'focus',
+ resolveEventData(
+ this.props,
+ {
+ value
+ },
+ 'value'
+ )
+ );
+
+ if (rendererEvent?.prevented) {
+ return;
+ }
+
+ onFocus?.(e);
}
- @bindRendererEvent('blur')
- handleBlur(e: any) {
- const {onBlur, trimContents, value, onChange} = this.props;
+ async handleBlur(e: any) {
+ const {onBlur, trimContents, value, onChange, dispatchEvent} = this.props;
this.setState(
{
@@ -334,18 +362,33 @@ export default class TextControl extends React.PureComponent<
}
);
+ const rendererEvent = await dispatchEvent(
+ 'blur',
+ resolveEventData(
+ this.props,
+ {
+ value
+ },
+ 'value'
+ )
+ );
+
+ if (rendererEvent?.prevented) {
+ return;
+ }
+
onBlur && onBlur(e);
}
async handleInputChange(evt: React.ChangeEvent) {
let value = this.transformValue(evt.currentTarget.value);
- const {creatable, multiple, onChange} = this.props;
- const dispatcher = await rendererEventDispatcher<
- TextProps,
- InputTextRendererEvent
- >(this.props, 'change', {value});
+ const {creatable, multiple, onChange, dispatchEvent} = this.props;
+ const rendererEvent = await dispatchEvent(
+ 'change',
+ resolveEventData(this.props, {value}, 'value')
+ );
- if (dispatcher?.prevented) {
+ if (rendererEvent?.prevented) {
return;
}
@@ -364,7 +407,8 @@ export default class TextControl extends React.PureComponent<
}
async handleKeyDown(evt: React.KeyboardEvent) {
- const {selectedOptions, onChange, multiple, creatable} = this.props;
+ const {selectedOptions, onChange, multiple, creatable, dispatchEvent} =
+ this.props;
if (selectedOptions.length && !this.state.inputValue && evt.keyCode === 8) {
evt.preventDefault();
@@ -402,12 +446,12 @@ export default class TextControl extends React.PureComponent<
value = this.normalizeValue(newValue).concat();
}
- const dispatcher = await rendererEventDispatcher<
- TextProps,
- InputTextRendererEvent
- >(this.props, 'enter', {value});
+ const rendererEvent = await dispatchEvent(
+ 'enter',
+ resolveEventData(this.props, {value}, 'value')
+ );
- if (dispatcher?.prevented) {
+ if (rendererEvent?.prevented) {
return;
}
@@ -505,14 +549,15 @@ export default class TextControl extends React.PureComponent<
@autobind
async handleNormalInputChange(e: React.ChangeEvent) {
- const {onChange} = this.props;
+ const {onChange, dispatchEvent} = this.props;
let value = e.currentTarget.value;
- const dispatcher = await rendererEventDispatcher<
- TextProps,
- InputTextRendererEvent
- >(this.props, 'change', {value: this.transformValue(value)});
- if (dispatcher?.prevented) {
+ const rendererEvent = await dispatchEvent(
+ 'change',
+ resolveEventData(this.props, {value: this.transformValue(value)}, 'value')
+ );
+
+ if (rendererEvent?.prevented) {
return;
}
diff --git a/packages/amis/src/renderers/Form/InputTree.tsx b/packages/amis/src/renderers/Form/InputTree.tsx
index 50da440a5..af6b17e52 100644
--- a/packages/amis/src/renderers/Form/InputTree.tsx
+++ b/packages/amis/src/renderers/Form/InputTree.tsx
@@ -8,7 +8,8 @@ import {
createObject,
ActionObject,
isPureVariable,
- resolveVariableAndFilter
+ resolveVariableAndFilter,
+ resolveEventData
} from 'amis-core';
import {Spinner} from 'amis-ui';
import {FormOptionsSchema, SchemaApi} from '../../Schema';
@@ -145,13 +146,11 @@ export default class TreeControl extends React.Component {
@autobind
async handleChange(value: any) {
- const {onChange, dispatchEvent, data} = this.props;
+ const {onChange, dispatchEvent} = this.props;
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value
- })
+ resolveEventData(this.props, {value}, 'value')
);
if (rendererEvent?.prevented) {
diff --git a/packages/amis/src/renderers/Form/MatrixCheckboxes.tsx b/packages/amis/src/renderers/Form/MatrixCheckboxes.tsx
index 619215a73..7fe13aa60 100644
--- a/packages/amis/src/renderers/Form/MatrixCheckboxes.tsx
+++ b/packages/amis/src/renderers/Form/MatrixCheckboxes.tsx
@@ -4,7 +4,12 @@
*/
import React from 'react';
-import {FormBaseControl, FormControlProps, FormItem} from 'amis-core';
+import {
+ FormBaseControl,
+ FormControlProps,
+ FormItem,
+ resolveEventData
+} from 'amis-core';
import {buildApi, isValidApi, isEffectiveApi} from 'amis-core';
import {Checkbox, Spinner} from 'amis-ui';
import {autobind, setVariable, createObject} from 'amis-core';
@@ -275,9 +280,7 @@ export default class MatrixCheckbox extends React.Component<
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value: value.concat()
- })
+ resolveEventData(this.props, {value: value.concat()}, 'value')
);
if (rendererEvent?.prevented) {
return;
diff --git a/packages/amis/src/renderers/Form/NestedSelect.tsx b/packages/amis/src/renderers/Form/NestedSelect.tsx
index 69bdee0a0..00057899d 100644
--- a/packages/amis/src/renderers/Form/NestedSelect.tsx
+++ b/packages/amis/src/renderers/Form/NestedSelect.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import {Overlay} from 'amis-core';
+import {Overlay, resolveEventData} from 'amis-core';
import {Checkbox} from 'amis-ui';
import {PopOver} from 'amis-core';
import {PopUp} from 'amis-ui';
@@ -139,12 +139,10 @@ export default class NestedSelectControl extends React.Component<
@autobind
async dispatchEvent(eventName: string, eventData: any = {}) {
- const {dispatchEvent, data} = this.props;
+ const {dispatchEvent} = this.props;
const rendererEvent = await dispatchEvent(
eventName,
- createObject(data, {
- ...eventData
- })
+ resolveEventData(this.props, eventData, 'value')
);
// 返回阻塞标识
return !!rendererEvent?.prevented;
diff --git a/packages/amis/src/renderers/Form/Picker.tsx b/packages/amis/src/renderers/Form/Picker.tsx
index f66b0d0d3..430d2fd8e 100644
--- a/packages/amis/src/renderers/Form/Picker.tsx
+++ b/packages/amis/src/renderers/Form/Picker.tsx
@@ -19,7 +19,8 @@ import {
isPureVariable,
resolveVariableAndFilter,
isApiOutdated,
- isEffectiveApi
+ isEffectiveApi,
+ resolveEventData
} from 'amis-core';
import {Html, Icon} from 'amis-ui';
import {FormOptionsSchema, SchemaTpl} from '../../Schema';
@@ -283,9 +284,14 @@ export default class PickerControl extends React.PureComponent<
});
additionalOptions.length && setOptions(options.concat(additionalOptions));
+ const option = multiple ? items : items[0];
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {value, option: items[0]})
+ resolveEventData(
+ this.props,
+ {value, option, selectedItems: option},
+ 'value'
+ )
);
if (rendererEvent?.prevented) {
return;
@@ -295,13 +301,14 @@ export default class PickerControl extends React.PureComponent<
}
@autobind
- async handleItemClick(itemlabel: string, itemid: string) {
- const {data, dispatchEvent, setOptions} = this.props;
+ async handleItemClick(item: any) {
+ const {data, dispatchEvent} = this.props;
const rendererEvent = await dispatchEvent(
'itemclick',
- createObject(data, {label: itemlabel, id: itemid})
+ createObject(data, {item})
);
+
if (rendererEvent?.prevented) {
return;
}
@@ -410,10 +417,7 @@ export default class PickerControl extends React.PureComponent<
className={`${ns}Picker-valueLabel`}
onClick={e => {
e.stopPropagation();
- this.handleItemClick(
- getVariable(item, labelField || 'label'),
- getVariable(item, 'id') || ''
- );
+ this.handleItemClick(item);
}}
>
{labelTpl ? (
diff --git a/packages/amis/src/renderers/Form/Radios.tsx b/packages/amis/src/renderers/Form/Radios.tsx
index b942bd25e..d63ffd8ad 100644
--- a/packages/amis/src/renderers/Form/Radios.tsx
+++ b/packages/amis/src/renderers/Form/Radios.tsx
@@ -5,7 +5,8 @@ import {
OptionsControl,
OptionsControlProps,
Option,
- FormOptionsControl
+ FormOptionsControl,
+ resolveEventData
} from 'amis-core';
import {autobind, isEmpty, createObject} from 'amis-core';
import {ActionObject} from 'amis-core';
@@ -70,10 +71,15 @@ export default class RadiosControl extends React.Component {
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value: option,
- options
- })
+ resolveEventData(
+ this.props,
+ {
+ value: option,
+ options,
+ items: options // 为了保持名字统一
+ },
+ 'value'
+ )
);
if (rendererEvent?.prevented) {
return;
diff --git a/packages/amis/src/renderers/Form/Select.tsx b/packages/amis/src/renderers/Form/Select.tsx
index 9eeaddbbe..c3b307a6b 100644
--- a/packages/amis/src/renderers/Form/Select.tsx
+++ b/packages/amis/src/renderers/Form/Select.tsx
@@ -4,7 +4,8 @@ import {
OptionsControl,
OptionsControlProps,
Option,
- FormOptionsControl
+ FormOptionsControl,
+ resolveEventData
} from 'amis-core';
import {normalizeOptions} from 'amis-core';
import find from 'lodash/find';
@@ -253,12 +254,17 @@ export default class SelectControl extends React.Component {
// 触发渲染器事件
const rendererEvent = await dispatchEvent(
eventName,
- createObject(data, {
- options,
- value: ['onEdit', 'onDelete'].includes(event)
- ? eventData
- : eventData && eventData.value
- })
+ resolveEventData(
+ this.props,
+ {
+ options,
+ items: options, // 为了保持名字统一
+ value: ['onEdit', 'onDelete'].includes(event)
+ ? eventData
+ : eventData && eventData.value
+ },
+ 'value'
+ )
);
if (rendererEvent?.prevented) {
return;
@@ -281,10 +287,15 @@ export default class SelectControl extends React.Component {
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value: newValue,
- options
- })
+ resolveEventData(
+ this.props,
+ {
+ value: newValue,
+ options,
+ items: options // 为了保持名字统一
+ },
+ 'value'
+ )
);
if (rendererEvent?.prevented) {
return;
diff --git a/packages/amis/src/renderers/Form/Switch.tsx b/packages/amis/src/renderers/Form/Switch.tsx
index def6f7d1a..d57442098 100644
--- a/packages/amis/src/renderers/Form/Switch.tsx
+++ b/packages/amis/src/renderers/Form/Switch.tsx
@@ -1,5 +1,10 @@
import React from 'react';
-import {FormItem, FormControlProps, FormBaseControl} from 'amis-core';
+import {
+ FormItem,
+ FormControlProps,
+ FormBaseControl,
+ resolveEventData
+} from 'amis-core';
import {Switch} from 'amis-ui';
import {createObject, autobind, isObject} from 'amis-core';
import {generateIcon} from 'amis-core';
@@ -64,12 +69,10 @@ export default class SwitchControl extends React.Component {
@autobind
async handleChange(checked: string | number | boolean) {
- const {dispatchEvent, data, onChange} = this.props;
+ const {dispatchEvent, onChange} = this.props;
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value: checked
- })
+ resolveEventData(this.props, {value: checked}, 'value')
);
if (rendererEvent?.prevented) {
return;
diff --git a/packages/amis/src/renderers/Form/TabsTransfer.tsx b/packages/amis/src/renderers/Form/TabsTransfer.tsx
index 099205985..984a54738 100644
--- a/packages/amis/src/renderers/Form/TabsTransfer.tsx
+++ b/packages/amis/src/renderers/Form/TabsTransfer.tsx
@@ -1,4 +1,4 @@
-import {OptionsControlProps, OptionsControl} from 'amis-core';
+import {OptionsControlProps, OptionsControl, resolveEventData} from 'amis-core';
import React from 'react';
import find from 'lodash/find';
import {Spinner} from 'amis-ui';
@@ -213,10 +213,18 @@ export class BaseTabsTransferRenderer<
setOptions(newOptions, true);
// 触发渲染器事件
- const rendererEvent = await dispatchEvent('change', {
- value: newValue,
- options
- });
+ const rendererEvent = await dispatchEvent(
+ 'change',
+ resolveEventData(
+ this.props,
+ {
+ value: newValue,
+ options,
+ items: options // 为了保持名字统一
+ },
+ 'value'
+ )
+ );
if (rendererEvent?.prevented) {
return;
}
diff --git a/packages/amis/src/renderers/Form/TabsTransferPicker.tsx b/packages/amis/src/renderers/Form/TabsTransferPicker.tsx
index ddb91bb15..6fff977e8 100644
--- a/packages/amis/src/renderers/Form/TabsTransferPicker.tsx
+++ b/packages/amis/src/renderers/Form/TabsTransferPicker.tsx
@@ -1,4 +1,4 @@
-import {OptionsControlProps, OptionsControl} from 'amis-core';
+import {OptionsControlProps, OptionsControl, resolveEventData} from 'amis-core';
import React from 'react';
import {Spinner} from 'amis-ui';
import {BaseTabsTransferRenderer} from './TabsTransfer';
@@ -43,8 +43,8 @@ export class TabsTransferPickerRenderer extends BaseTabsTransferRenderer(
- 'change',
- undefined,
- false
- )
handleChange(e: React.ChangeEvent) {
- const {onChange} = this.props;
+ const {onChange, dispatchEvent} = this.props;
+
+ dispatchEvent('change', resolveEventData(this.props, {value: e}, 'value'));
+
onChange && onChange(e);
}
@autobind
- @bindRendererEvent('focus')
handleFocus(e: React.FocusEvent) {
- const {onFocus} = this.props;
+ const {onFocus, dispatchEvent, value} = this.props;
this.setState(
{
focused: true
},
- () => {
+ async () => {
+ const rendererEvent = await dispatchEvent(
+ 'focus',
+ resolveEventData(this.props, {value}, 'value')
+ );
+
+ if (rendererEvent?.prevented) {
+ return;
+ }
onFocus && onFocus(e);
}
);
}
@autobind
- @bindRendererEvent('blur')
handleBlur(e: React.FocusEvent) {
- const {onBlur, trimContents, value, onChange} = this.props;
+ const {onBlur, trimContents, value, onChange, dispatchEvent} = this.props;
this.setState(
{
focused: false
},
- () => {
+ async () => {
if (trimContents && value && typeof value === 'string') {
onChange(value.trim());
}
+ const rendererEvent = await dispatchEvent(
+ 'blur',
+ resolveEventData(this.props, {value}, 'value')
+ );
+
+ if (rendererEvent?.prevented) {
+ return;
+ }
+
onBlur && onBlur(e);
}
);
diff --git a/packages/amis/src/renderers/Form/Transfer.tsx b/packages/amis/src/renderers/Form/Transfer.tsx
index 551d57efc..8576e2a53 100644
--- a/packages/amis/src/renderers/Form/Transfer.tsx
+++ b/packages/amis/src/renderers/Form/Transfer.tsx
@@ -4,7 +4,8 @@ import find from 'lodash/find';
import {
OptionsControlProps,
OptionsControl,
- FormOptionsControl
+ FormOptionsControl,
+ resolveEventData
} from 'amis-core';
import {Transfer} from 'amis-ui';
import type {Option} from 'amis-core';
@@ -230,10 +231,18 @@ export class BaseTransferRenderer<
setOptions(newOptions, true);
// 触发渲染器事件
- const rendererEvent = await dispatchEvent('change', {
- value: newValue,
- options
- });
+ const rendererEvent = await dispatchEvent(
+ 'change',
+ resolveEventData(
+ this.props,
+ {
+ value: newValue,
+ options,
+ items: options // 为了保持名字统一
+ },
+ 'value'
+ )
+ );
if (rendererEvent?.prevented) {
return;
}
@@ -387,7 +396,10 @@ export class BaseTransferRenderer<
@autobind
onSelectAll(options: Option[]) {
const {dispatchEvent, data} = this.props;
- dispatchEvent('selectAll', createObject(data, {options}));
+ dispatchEvent(
+ 'selectAll',
+ resolveEventData(this.props, {items: options}, 'value')
+ );
}
// 动作
@@ -482,7 +494,6 @@ export class BaseTransferRenderer<
labelField={labelField}
optionItemRender={this.optionItemRender}
resultItemRender={this.resultItemRender}
- onSelectAll={this.onSelectAll}
onRef={this.getRef}
/>
diff --git a/packages/amis/src/renderers/Form/TransferPicker.tsx b/packages/amis/src/renderers/Form/TransferPicker.tsx
index 69519571f..287d4f513 100644
--- a/packages/amis/src/renderers/Form/TransferPicker.tsx
+++ b/packages/amis/src/renderers/Form/TransferPicker.tsx
@@ -1,4 +1,4 @@
-import {OptionsControlProps, OptionsControl} from 'amis-core';
+import {OptionsControlProps, OptionsControl, resolveEventData} from 'amis-core';
import React from 'react';
import {Spinner} from 'amis-ui';
import {BaseTransferRenderer, TransferControlSchema} from './Transfer';
@@ -41,8 +41,8 @@ export interface TabsTransferProps
export class TransferPickerRenderer extends BaseTransferRenderer {
@autobind
dispatchEvent(name: string) {
- const {dispatchEvent, data, value} = this.props;
- dispatchEvent(name, createObject(data, {value}));
+ const {dispatchEvent, value} = this.props;
+ dispatchEvent(name, resolveEventData(this.props, {value}, 'value'));
}
// 动作
diff --git a/packages/amis/src/renderers/Form/TreeSelect.tsx b/packages/amis/src/renderers/Form/TreeSelect.tsx
index c06648ab9..d376f4562 100644
--- a/packages/amis/src/renderers/Form/TreeSelect.tsx
+++ b/packages/amis/src/renderers/Form/TreeSelect.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import {Overlay} from 'amis-core';
+import {Overlay, resolveEventData} from 'amis-core';
import {PopOver} from 'amis-core';
import {PopUp} from 'amis-ui';
@@ -202,23 +202,13 @@ export default class TreeSelectControl extends React.Component<
}
handleFocus(e: any) {
- const {dispatchEvent, value, data} = this.props;
- dispatchEvent(
- 'focus',
- createObject(data, {
- value
- })
- );
+ const {dispatchEvent, value} = this.props;
+ dispatchEvent('focus', resolveEventData(this.props, {value}, 'value'));
}
handleBlur(e: any) {
const {dispatchEvent, value, data} = this.props;
- dispatchEvent(
- 'blur',
- createObject(data, {
- value
- })
- );
+ dispatchEvent('blur', resolveEventData(this.props, {value}, 'value'));
}
handleKeyPress(e: React.KeyboardEvent) {
@@ -453,9 +443,7 @@ export default class TreeSelectControl extends React.Component<
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value
- })
+ resolveEventData(this.props, {value}, 'value')
);
if (rendererEvent?.prevented) {
diff --git a/packages/amis/src/renderers/Form/UserSelect.tsx b/packages/amis/src/renderers/Form/UserSelect.tsx
index 067daf551..8da99e6e6 100644
--- a/packages/amis/src/renderers/Form/UserSelect.tsx
+++ b/packages/amis/src/renderers/Form/UserSelect.tsx
@@ -4,7 +4,8 @@ import {
OptionsControl,
OptionsControlProps,
Option,
- FormOptionsControl
+ FormOptionsControl,
+ resolveEventData
} from 'amis-core';
import {UserSelect} from 'amis-ui';
import {UserTabSelect} from 'amis-ui';
@@ -187,10 +188,15 @@ export default class UserSelectControl extends React.Component<
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value: newValue,
- options
- })
+ resolveEventData(
+ this.props,
+ {
+ value: newValue,
+ options,
+ items: options // 为了保持名字统一
+ },
+ 'value'
+ )
);
if (rendererEvent?.prevented) {
return;
diff --git a/packages/amis/src/renderers/Tabs.tsx b/packages/amis/src/renderers/Tabs.tsx
index 2e71b5418..6f99c0ab0 100644
--- a/packages/amis/src/renderers/Tabs.tsx
+++ b/packages/amis/src/renderers/Tabs.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import {Renderer, RendererProps} from 'amis-core';
+import {Renderer, RendererProps, resolveEventData} from 'amis-core';
import {ActionObject, Schema, SchemaNode} from 'amis-core';
import find from 'lodash/find';
import {
@@ -619,9 +619,13 @@ export default class Tabs extends React.Component {
const rendererEvent = await dispatchEvent(
'change',
- createObject(data, {
- value: tab?.hash ? tab?.hash : key + 1
- })
+ resolveEventData(
+ this.props,
+ {
+ value: tab?.hash ? tab?.hash : key + 1
+ },
+ 'value'
+ )
);
if (rendererEvent?.prevented) {
return;