feat:ajax动作支持返回status和msg&支持静默模式 (#4912)

* feat:ajax动作支持返回status和msg&支持静默模式

* jest:更新ajax动作测试用例
This commit is contained in:
hsm-lv 2022-07-19 13:21:45 +08:00 committed by GitHub
parent 3890a174d4
commit 4a935d3499
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 203 additions and 52 deletions

View File

@ -95,7 +95,7 @@ order: 9
### 发送 http 请求
通过配置`actionType: 'ajax'`和`api`实现 http 请求发送,该动作需实现 env.fetcher(config: fetcherConfig) => Promise<fetcherResult>
通过配置`actionType: 'ajax'`和`api`实现 http 请求发送,该动作需实现 `env.fetcher` 请求器。请求结果的状态、数据、消息分别默认缓存在 `event.data.responseStatus`、`event.data.responseData`或`event.data.{{outputVar}}`、`event.data.responseMsg`。< 2.0.3 以以下版本请求返回数据默认缓存在 `event.data`。`outputVar` 配置用于解决串行或者并行发送多个 http 请求的场景
```schema
{
@ -126,6 +126,51 @@ order: 9
},
age: 18
}
},
{
actionType: 'toast',
expression: '${event.data.responseStatus === 0}',
args: {
msg: '${event.data|json}'
}
}
]
}
}
},
{
type: 'button',
id: 'b_001',
label: '发送 Ajax 请求(静默模式)',
level: 'primary',
"confirmText": "确认要发出这个请求?",
className: 'm',
onEvent: {
click: {
actions: [
{
actionType: 'ajax',
args: {
api: {
url: 'https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/initData?name=${name}',
method: 'get'
},
messages: {
success: '成功了!欧耶',
failed: '失败了呢。。'
},
age: 18,
options: {
silent: true
}
}
},
{
actionType: 'toast',
expression: '${event.data.responseStatus === 0}',
args: {
msg: '${event.data|json}'
}
}
]
}
@ -2253,9 +2298,9 @@ registerAction('my-action', new MyAction());
}
```
**存储异步请求返回的数据**
**引用 http 请求动作返回的数据**
通过 `outputVar` 指定输出的变量名,其他动作可以通过`${event.data.{{outputVar}}}`来获取变量值,如果未指定 `outputVar` ,则直接存储到`event.data`
http 请求动作执行结束后,后面的动作可以通过 `event.data.responseStatus`、`event.data.responseData`或`event.data.{{outputVar}}`、`event.data.responseMsg`来获取请求结果的状态、数据、消息
```schema
{
@ -2271,18 +2316,13 @@ registerAction('my-action', new MyAction());
{
actionType: 'ajax',
args: {
api: 'https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm',
messages: {
success: '成功了!欧耶',
failed: '失败了呢。。'
}
},
outputVar: 'ajax1'
api: 'https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm'
}
},
{
actionType: 'dialog',
args: {
id: '${event.data.ajax1.id}'
id: '${event.data.responseData.id}'
},
dialog: {
type: 'dialog',

View File

@ -59,32 +59,51 @@ export class AjaxAction implements RendererAction {
action.args?.options ?? {}
);
if (!isEmpty(result.data) || result.ok) {
const responseData = normalizeApiResponseData(result.data);
// 记录请求返回的数据
event.setData(
createObject(
event.data,
action.outputVar
? {
[`${action.outputVar}`]: responseData
}
: responseData
)
);
const responseData =
!isEmpty(result.data) || result.ok
? normalizeApiResponseData(result.data)
: null;
// 记录请求返回的数据
event.setData(
createObject(event.data, {
...responseData, // 兼容历史配置
[action.outputVar || 'responseData']: responseData,
responseStatus: result.status,
responseMsg: result.msg
})
);
if (!action.args?.options?.silent) {
if (!result.ok) {
throw new ServerError(
action.args?.messages?.failed ?? result.msg,
result
);
} else {
const msg = action.args?.messages?.success ?? result.msg;
msg &&
env.notify(
'success',
msg,
result.msgTimeout !== undefined
? {
closeButton: true,
timeout: result.msgTimeout
}
: undefined
);
}
}
if (!result.ok) {
throw new ServerError(
action.args?.messages?.failed ?? result.msg,
result
);
} else {
const msg = action.args?.messages?.success ?? result.msg;
msg &&
return result.data;
} catch (e) {
if (!action.args?.options?.silent) {
if (e.type === 'ServerError') {
const result = (e as ServerError).response;
env.notify(
'success',
msg,
'error',
e.message,
result.msgTimeout !== undefined
? {
closeButton: true,
@ -92,24 +111,9 @@ export class AjaxAction implements RendererAction {
}
: undefined
);
}
return result.data;
} catch (e) {
if (e.type === 'ServerError') {
const result = (e as ServerError).response;
env.notify(
'error',
e.message,
result.msgTimeout !== undefined
? {
closeButton: true,
timeout: result.msgTimeout
}
: undefined
);
} else {
env.notify('error', e.message);
} else {
env.notify('error', e.message);
}
}
// 不阻塞后面执行

View File

@ -29,6 +29,72 @@ exports[`EventAction:ajax 1`] = `
18岁的天空
</span>
</span>
<button
class="cxd-Button cxd-Button--primary"
type="button"
>
<span>
发送请求2
</span>
</button>
<span
class="cxd-TplField"
>
<span>
岁的天空status:msg:
</span>
</span>
</div>
</div>
</div>
</div>
</div>
`;
exports[`EventAction:ajax 2`] = `
<div>
<div
class="cxd-Page"
>
<div
class="cxd-Page-content"
>
<div
class="cxd-Page-main"
>
<div
class="cxd-Page-body"
>
<button
class="cxd-Button cxd-Button--primary"
type="button"
>
<span>
发送请求
</span>
</button>
<span
class="cxd-TplField"
>
<span>
18岁的天空
</span>
</span>
<button
class="cxd-Button cxd-Button--primary"
type="button"
>
<span>
发送请求2
</span>
</button>
<span
class="cxd-TplField"
>
<span>
18岁的天空status:0msg:ok
</span>
</span>
</div>
</div>
</div>

View File

@ -59,6 +59,41 @@ test('EventAction:ajax', async () => {
{
type: 'tpl',
tpl: '${age}岁的天空'
},
{
type: 'button',
label: '发送请求2',
level: 'primary',
onEvent: {
click: {
actions: [
{
actionType: 'ajax',
args: {
api: {
url: 'api/xxx',
method: 'get'
},
messages: {
success: '成功了!欧耶',
failed: '失败了呢。。'
}
}
},
{
actionType: 'setValue',
componentId: 'page_001',
args: {
value: '${event.data}'
}
}
]
}
}
},
{
type: 'tpl',
tpl: '${responseData.age}岁的天空status:${responseStatus}msg:${responseMsg}'
}
]
},
@ -74,4 +109,10 @@ test('EventAction:ajax', async () => {
expect(getByText('18岁的天空')).toBeInTheDocument();
});
expect(container).toMatchSnapshot();
fireEvent.click(getByText('发送请求2'));
await waitFor(() => {
expect(getByText('18岁的天空status:0msg:ok')).toBeInTheDocument();
});
expect(container).toMatchSnapshot();
});