mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
chore:表单校验和提交动作支持返回结果
This commit is contained in:
parent
d7ee9a4db8
commit
59f8a3ec2d
@ -1469,13 +1469,387 @@ Form 支持轮询初始化接口,步骤如下:
|
||||
|
||||
当前组件对外暴露以下特性动作,其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作,动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数,详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。
|
||||
|
||||
| 动作名称 | 动作配置 | 说明 |
|
||||
| --------- | ------------------------------ | -------------------------- |
|
||||
| submit | - | 提交表单 |
|
||||
| reset | - | 重置表单 |
|
||||
| clear | - | 清空表单 |
|
||||
| validate | - | 校验表单 |
|
||||
| reload | - | 刷新(重新加载) |
|
||||
| setValue | `value: object` 更新的表单数据 | 更新数据,对数据进行 merge |
|
||||
| static | - | 表单切换为静态展示 |
|
||||
| nonstatic | - | 表单切换为普通输入态 |
|
||||
| 动作名称 | 动作配置 | 说明 |
|
||||
| --------- | --------------------------------------------------- | -------------------------- |
|
||||
| validate | `outputVar: string` 校验结果,默认为 validateResult | 校验表单 |
|
||||
| submit | `outputVar: string` 提交结果,默认为 submitResult | 提交表单 |
|
||||
| setValue | `value: object` 更新的表单数据 | 更新数据,对数据进行 merge |
|
||||
| reload | - | 刷新(重新加载) |
|
||||
| reset | - | 重置表单 |
|
||||
| clear | - | 清空表单 |
|
||||
| static | - | 表单切换为静态展示 |
|
||||
| nonstatic | - | 表单切换为普通输入态 |
|
||||
|
||||
### validate
|
||||
|
||||
校验结果默认缓存在`${event.data.validateResult}`,`true`表示校验成功,`false`表示检验失败。可以通过添加`outputVar`配置来修改缓存的变量。
|
||||
|
||||
校验结果的结构如下:
|
||||
|
||||
```json
|
||||
{
|
||||
// 是否成功。true表示成功,false表示失败
|
||||
"error": true,
|
||||
// 表单项报错信息。key值为该表单项的name值
|
||||
"errors": {
|
||||
"email": ["Email 格式不正确"],
|
||||
...
|
||||
},
|
||||
// 提交验证的表单数据
|
||||
"payload": {
|
||||
"name": "amis",
|
||||
"email": "amis@baidu"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```schema: scope="body"
|
||||
[
|
||||
{
|
||||
"type": "button",
|
||||
"label": "校验表单",
|
||||
className: "mb-2",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "validate",
|
||||
"componentId": "form_validate",
|
||||
"outputVar": "form_validata_result",
|
||||
"stopPropagation": "${event.data.form_validata_result.error}"
|
||||
},
|
||||
{
|
||||
"actionType": "toast",
|
||||
"args": {
|
||||
"msg": "${event.data.form_validata_result|json}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "form",
|
||||
"id": "form_validate",
|
||||
"api": "/api/mock2/form/saveForm",
|
||||
"body": [
|
||||
{
|
||||
"type": "input-text",
|
||||
"name": "name",
|
||||
"label": "姓名:",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "email",
|
||||
"type": "input-text",
|
||||
"label": "邮箱:",
|
||||
"required": true,
|
||||
"validations": {
|
||||
"isEmail": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### submit
|
||||
|
||||
提交结果默认缓存在`${event.data.submitResult}`,可以通过添加`outputVar`配置来修改缓存的变量。
|
||||
|
||||
提交结果的结构如下:
|
||||
|
||||
```json
|
||||
{
|
||||
// 是否成功。true表示成功,false表示失败
|
||||
"error": true,
|
||||
// 错误信息。如果是校验失败,则errors为表单项报错信息,key值为该表单项的name值
|
||||
"errors": {
|
||||
...
|
||||
},
|
||||
// 提交的表单数据
|
||||
"payload": {
|
||||
"name": "amis",
|
||||
"email": "amis@baidu.com"
|
||||
},
|
||||
// 提交请求返回的响应结果数据
|
||||
"responseData": {
|
||||
"id": "1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```schema: scope="body"
|
||||
[
|
||||
{
|
||||
"type": "button",
|
||||
"label": "提交表单",
|
||||
className: "mb-2",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "submit",
|
||||
"componentId": "form_submit",
|
||||
"outputVar": "form_submit_result"
|
||||
},
|
||||
{
|
||||
"actionType": "toast",
|
||||
"args": {
|
||||
"msg": "提交结果:${event.data.form_submit_result|json}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "form",
|
||||
"id": "form_submit",
|
||||
"api": "/api/mock2/form/saveForm",
|
||||
"body": [
|
||||
{
|
||||
"type": "input-text",
|
||||
"name": "name",
|
||||
"label": "姓名:",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "email",
|
||||
"type": "input-text",
|
||||
"label": "邮箱:",
|
||||
"required": true,
|
||||
"validations": {
|
||||
"isEmail": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### setValue
|
||||
|
||||
通过`setValue`来更新表单数据,其中`value`中的数据将和目标表单的数据做合并,即同名覆盖。
|
||||
|
||||
```schema: scope="body"
|
||||
[
|
||||
{
|
||||
"type": "button",
|
||||
"label": "修改表单数据",
|
||||
className: "mb-2",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "setValue",
|
||||
"componentId": "form_setvalue",
|
||||
"args": {
|
||||
"value": {
|
||||
"name": "amis",
|
||||
"email": "amis@baidu.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "form",
|
||||
"id": "form_setvalue",
|
||||
"body": [
|
||||
{
|
||||
"type": "input-text",
|
||||
"name": "name",
|
||||
"label": "姓名:"
|
||||
},
|
||||
{
|
||||
"name": "email",
|
||||
"type": "input-text",
|
||||
"label": "邮箱:"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### reload
|
||||
|
||||
通过`reload`来重新请求表单的初始化接口,实现表单刷新。
|
||||
|
||||
```schema: scope="body"
|
||||
[
|
||||
{
|
||||
"type": "button",
|
||||
"label": "刷新表单",
|
||||
className: "mb-2",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "reload",
|
||||
"componentId": "form_reload"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "form",
|
||||
"id": "form_reload",
|
||||
"debug": true,
|
||||
"initApi": "/api/mock2/form/initData",
|
||||
"body": [
|
||||
{
|
||||
"type": "input-text",
|
||||
"name": "name",
|
||||
"label": "姓名:"
|
||||
},
|
||||
{
|
||||
"name": "author",
|
||||
"type": "input-text",
|
||||
"label": "作者:"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### reset
|
||||
|
||||
通过`reset`将表单数据重置为初始数据,初始数据可以是静态数据或初始化接口返回的数据。
|
||||
|
||||
```schema: scope="body"
|
||||
[
|
||||
{
|
||||
"type": "button",
|
||||
"label": "重置表单",
|
||||
className: "mb-2",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "reset",
|
||||
"componentId": "form_reset"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "form",
|
||||
"id": "form_reset",
|
||||
"initApi": "/api/mock2/form/initData",
|
||||
"body": [
|
||||
{
|
||||
"type": "alert",
|
||||
"body": "修改表单项的值,然后点击【重置表单】,表单数据将被重置为初始化数据"
|
||||
},
|
||||
{
|
||||
"type": "input-text",
|
||||
"name": "name",
|
||||
"label": "姓名:"
|
||||
},
|
||||
{
|
||||
"name": "author",
|
||||
"type": "input-text",
|
||||
"label": "作者:"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### clear
|
||||
|
||||
通过`clear`来清空表单中的表单项数据,不包含`hidden`类型、未绑定表单项的初始化数据字段。
|
||||
|
||||
```schema: scope="body"
|
||||
[
|
||||
{
|
||||
"type": "button",
|
||||
"label": "清空表单",
|
||||
className: "mb-2",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "clear",
|
||||
"componentId": "form_clear"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "form",
|
||||
"id": "form_clear",
|
||||
"debug": true,
|
||||
"initApi": "/api/mock2/form/initData",
|
||||
"body": [
|
||||
{
|
||||
"type": "input-text",
|
||||
"name": "name",
|
||||
"label": "姓名:"
|
||||
},
|
||||
{
|
||||
"name": "author",
|
||||
"type": "hidden",
|
||||
"label": "作者:"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### static 和 nonstatic
|
||||
|
||||
```schema: scope="body"
|
||||
[
|
||||
{
|
||||
"type": "button",
|
||||
"label": "静态模式",
|
||||
"className": "mr-2 mb-2",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "static",
|
||||
"componentId": "form_static"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"label": "非静态模式",
|
||||
"className": "mr-2 mb-2",
|
||||
"onEvent": {
|
||||
"click": {
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "nonstatic",
|
||||
"componentId": "form_static"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "form",
|
||||
"id": "form_static",
|
||||
"title": "表单",
|
||||
"body": [
|
||||
{
|
||||
"type": "input-text",
|
||||
"name": "text",
|
||||
"label": "输入框",
|
||||
"mode": "horizontal",
|
||||
"value": "text"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {RendererEvent} from '../utils/renderer-event';
|
||||
import {createObject, isEmpty} from '../utils/helper';
|
||||
import {
|
||||
RendererAction,
|
||||
ListenerAction,
|
||||
@ -116,7 +117,42 @@ export class CmptAction implements RendererAction {
|
||||
}
|
||||
|
||||
// 执行组件动作
|
||||
return component?.doAction?.(action, action.args);
|
||||
try {
|
||||
const result = await component?.doAction?.(action, action.args, true);
|
||||
|
||||
if (['validate', 'submit'].includes(action.actionType)) {
|
||||
event.setData(
|
||||
createObject(event.data, {
|
||||
[action.outputVar || `${action.actionType}Result`]: {
|
||||
error:
|
||||
(action.actionType as any) === 'validate' ? !result : false,
|
||||
errors: component.props.store.errors,
|
||||
payload: component.props.data,
|
||||
responseData:
|
||||
(action.actionType as any) === 'submit'
|
||||
? component.props.$schema?.api
|
||||
? result
|
||||
: undefined
|
||||
: undefined
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
return result;
|
||||
} catch (e) {
|
||||
if ((action.actionType as any) === 'submit') {
|
||||
const errors = component.props.store.errors;
|
||||
event.setData(
|
||||
createObject(event.data, {
|
||||
[action.outputVar || 'submitResult']: {
|
||||
error: true,
|
||||
errors: isEmpty(errors) ? e : errors,
|
||||
payload: component.props.data
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1202,7 +1202,7 @@ export default class Form extends React.Component<FormProps, object> {
|
||||
}
|
||||
}
|
||||
|
||||
// return values;
|
||||
return createObject(store.data, response);
|
||||
});
|
||||
} else {
|
||||
// type为submit,但是没有配api以及target时,只派发事件
|
||||
@ -1256,7 +1256,7 @@ export default class Form extends React.Component<FormProps, object> {
|
||||
store.clear(onReset);
|
||||
} else if (action.actionType === 'validate') {
|
||||
store.setCurrentAction(action);
|
||||
this.validate(true);
|
||||
return this.validate(true);
|
||||
} else if (action.actionType === 'dialog') {
|
||||
store.setCurrentAction(action);
|
||||
store.openDialog(data, undefined, action.callback);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {ListenerAction, ListenerContext, runActions} from '../actions/Action';
|
||||
import {RendererProps} from '../factory';
|
||||
import {IScopedContext} from '../Scoped';
|
||||
import {createObject} from './object';
|
||||
import {createObject, extendObject} from './object';
|
||||
import debounce from 'lodash/debounce';
|
||||
|
||||
export interface debounceConfig {
|
||||
@ -65,7 +65,7 @@ export function createRendererEvent<T extends RendererEventContext>(
|
||||
context: T
|
||||
): RendererEvent<T> {
|
||||
const rendererEvent = {
|
||||
context,
|
||||
context: extendObject({pristineData: context.data}, context),
|
||||
type,
|
||||
prevented: false,
|
||||
stoped: false,
|
||||
@ -81,6 +81,10 @@ export function createRendererEvent<T extends RendererEventContext>(
|
||||
return rendererEvent.context.data;
|
||||
},
|
||||
|
||||
get pristineData() {
|
||||
return rendererEvent.context.pristineData;
|
||||
},
|
||||
|
||||
setData(data: any) {
|
||||
rendererEvent.context.data = data;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user