Merge pull request #7728 from hsm-lv/fix-ajaxaction

fix:ajax动作不配置data时不应该发送数据
This commit is contained in:
hsm-lv 2023-08-07 19:59:47 +08:00 committed by GitHub
commit f6a35036e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 320 additions and 3 deletions

View File

@ -281,7 +281,22 @@ run action ajax
]
}
}
}
]
}
```
#### 静默模式
当配置`options.silent: true`时,请求完成后不会弹出提示信息。
```schema
{
type: 'page',
data: {
name: 'lll'
},
body: [
{
type: 'button',
id: 'b_001',
@ -324,6 +339,106 @@ run action ajax
}
```
#### 可读取的数据
请求配置中可读取的数据包含事件源所在数据域和动作执行产生的数据。可以通过`api.data`配置数据映射来读取所需数据。例如:
- 取所在数据域的数据:通过`"name": "${name}", "email": "${email}"`来映射表单校验数据(只适用于事件源在表单内的情况)
- 取动作产生的数据:通过`"name": "${event.data.validateResult.payload.name}", "email": "${event.data.validateResult.payload.email}"`来映射表单校验数据,这种是获取前面表单校验动作的校验结果数据。通过`"&": "${event.data.validateResult.payload}"`展开表单校验数据,结果相同,这是一个数据映射小技巧
```schema
{
"type": "page",
"body": [
{
"type": "button",
"label": "表单外的校验按钮",
"className": "mb-2",
level: 'primary',
"onEvent": {
"click": {
"actions": [
{
"componentId": "form_validate",
"outputVar": "validateResult",
"actionType": "validate"
},
{
"outputVar": "responseResult",
"actionType": "ajax",
"api": {
"method": "post",
"url": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm",
"data": {
"name": "${name}",
"email": "${email}"
}
}
}
]
}
},
"id": "u:bd7adb583ec8"
},
{
"type": "form",
"id": "form_validate",
"body": [
{
"type": "input-text",
"name": "name",
"label": "姓名:",
"required": true,
"id": "u:fbbc02500df6"
},
{
"name": "email",
"type": "input-text",
"label": "邮箱:",
"required": true,
"validations": {
"isEmail": true
},
"id": "u:830d0bad3e6a"
}
],
"actions": [
{
"type": "button",
"label": "表单内的校验按钮",
level: 'primary',
"onEvent": {
"click": {
"actions": [
{
"componentId": "form_validate",
"outputVar": "validateResult",
"actionType": "validate"
},
{
"outputVar": "responseResult",
"actionType": "ajax",
"api": {
"method": "post",
"url": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm",
"data": {
"name": "${name}",
"email": "${email}"
}
}
}
]
}
},
"id": "u:bd7adb583ec8"
}
]
}
],
"id": "u:d79af3431de1"
}
```
**动作属性**
| 属性名 | 类型 | 默认值 | 说明 |

View File

@ -1,5 +1,5 @@
import {Api, ApiObject} from '../types';
import {normalizeApiResponseData} from '../utils/api';
import {normalizeApi, normalizeApiResponseData} from '../utils/api';
import {ServerError} from '../utils/errors';
import {createObject, isEmpty} from '../utils/helper';
import {RendererEvent} from '../utils/renderer-event';
@ -42,6 +42,11 @@ export class AjaxAction implements RendererAction {
if (!renderer.props.env?.fetcher) {
throw new Error('env.fetcher is required!');
}
if (!action.api) {
throw new Error('api is required!');
}
if (this.fetcherType === 'download' && action.actionType === 'download') {
if ((action as any).api) {
(action as any).api.responseType = 'blob';
@ -51,9 +56,19 @@ export class AjaxAction implements RendererAction {
const env = event.context.env;
const silent = action?.options?.silent;
const messages = (action?.api as ApiObject)?.messages;
let api = normalizeApi(action.api);
// 如果没配置data数据映射则给一个空对象避免将当前数据域作为接口请求参数
if ((api as any)?.data == undefined) {
api = {
...api,
data: {}
};
}
try {
const result = await env.fetcher(
action?.api,
api,
action.data ?? {},
action?.options ?? {}
);

View File

@ -422,3 +422,190 @@ test('EventAction:ajax data2', async () => {
});
});
});
test('EventAction:ajax data3', async () => {
const fetcher = jest.fn().mockImplementation(() =>
Promise.resolve({
data: {
status: 0,
msg: 'ok',
data: {
name: 'amis',
age: 18
}
}
})
);
const {getByText, container}: any = render(
amisRender(
{
type: 'page',
body: [
{
type: 'button',
label: '表单外的校验按钮',
className: 'mb-2',
level: 'primary',
onEvent: {
click: {
actions: [
{
componentId: 'form_validate',
outputVar: 'validateResult',
actionType: 'validate'
},
{
outputVar: 'responseResult',
actionType: 'ajax',
api: {
method: 'post',
url: '/api/xxx1',
data: {
name: '${name}',
email: '${email}'
}
}
}
]
}
}
},
{
type: 'form',
id: 'form_validate',
data: {
name: 'amis',
email: 'amis@baidu.com'
},
body: [
{
type: 'input-text',
name: 'name',
label: '姓名:',
required: true
},
{
name: 'email',
type: 'input-text',
label: '邮箱:',
required: true,
validations: {
isEmail: true
}
}
],
actions: [
{
type: 'button',
label: '表单内的校验按钮',
level: 'primary',
onEvent: {
click: {
actions: [
{
componentId: 'form_validate',
outputVar: 'validateResult',
actionType: 'validate'
},
{
outputVar: 'responseResult',
actionType: 'ajax',
api: {
method: 'post',
url: '/api/xxx2',
data: {
name: '${name}',
email: '${email}'
}
}
}
]
}
}
},
{
type: 'button',
label: '无data',
level: 'primary',
onEvent: {
click: {
actions: [
{
componentId: 'form_validate',
outputVar: 'validateResult',
actionType: 'validate'
},
{
outputVar: 'responseResult',
actionType: 'ajax',
api: {
method: 'post',
url: '/api/xxx3'
}
}
]
}
}
},
{
type: 'button',
label: '字符串api无参数',
level: 'primary',
onEvent: {
click: {
actions: [
{
componentId: 'form_validate',
outputVar: 'validateResult',
actionType: 'validate'
},
{
outputVar: 'responseResult',
actionType: 'ajax',
api: 'post:/api/xxx4'
}
]
}
}
}
]
}
]
},
{},
makeEnv({
fetcher
})
)
);
await waitFor(() => {
expect(getByText('表单外的校验按钮')).toBeInTheDocument();
expect(getByText('表单内的校验按钮')).toBeInTheDocument();
expect(getByText('无data')).toBeInTheDocument();
expect(getByText('字符串api无参数')).toBeInTheDocument();
});
fireEvent.click(getByText(/表单外的校验按钮/));
fireEvent.click(getByText(/表单内的校验按钮/));
fireEvent.click(getByText(/无data/));
fireEvent.click(getByText(/字符串api无参数/));
await waitFor(() => {
expect(fetcher).toHaveBeenCalledTimes(4);
expect(fetcher.mock.calls[0][0].url).toEqual('/api/xxx1');
expect(fetcher.mock.calls[0][0].data).toMatchObject({
name: '',
email: ''
});
expect(fetcher.mock.calls[1][0].url).toEqual('/api/xxx2');
expect(fetcher.mock.calls[1][0].data).toMatchObject({
name: 'amis',
email: 'amis@baidu.com'
});
expect(fetcher.mock.calls[2][0].url).toEqual('/api/xxx3');
expect(fetcher.mock.calls[2][0].data).toMatchObject({});
expect(fetcher.mock.calls[3][0].url).toEqual('/api/xxx4');
expect(fetcher.mock.calls[3][0].data).toMatchObject({});
});
});