add form submit example
This commit is contained in:
21
packages/dooringx-doc/src/docs/4.4.md
Normal file
21
packages/dooringx-doc/src/docs/4.4.md
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
title: 表单验证提交思路
|
||||
sTitle: 常见问题
|
||||
order: 20
|
||||
---
|
||||
|
||||
表单验证提交有非常多的做法,因为数据全部是联通的,或者直接写个表单组件也可以。
|
||||
|
||||
在不使用表单组件时,简单的做法是为每个输入组件做个验证函数与提交函数。
|
||||
|
||||
这样是否验证就取决于用户的选取,而抛出的输入可以让用户选择放到哪,并由用户去命名变量。
|
||||
|
||||
在点击提交按钮时,调用所有组件的验证函数与提交函数,使其抛给上下文,再通过上下文聚合函数聚合成对象,最后可以通过发送函数发送给对应后端,从而完成整个流程。你可以在example中试下这个demo。
|
||||
|
||||
如果操作人员能看懂后端提供的接口文档,那么就可以让操作人员自己通过命名来拼出后端想要的字段。
|
||||
|
||||
如果不需要文档,那么某些值也可以在开发时写死。
|
||||
|
||||
另外的做法是可以专门写个提交按钮,固定了参数,以及部分规则,比如规定在页面中的所有表单都会被收集提交。
|
||||
|
||||
那么我们可以利用数据源,将所有表单输出内容自动提交给数据源,最后的提交按钮按数据源规定格式的key提取,发送给后端。
|
@@ -2,7 +2,7 @@
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-08-03 10:45:06
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-08-03 10:45:07
|
||||
* @LastEditTime: 2021-08-05 14:35:49
|
||||
* @FilePath: \dooringx\packages\dooringx-example\src\plugin\formComponents\switch.tsx
|
||||
*/
|
||||
import React, { useMemo, memo } from 'react';
|
||||
@@ -25,10 +25,10 @@ const MSwitch = (props: MSwitchProps) => {
|
||||
const store = props.config.getStore();
|
||||
return (
|
||||
<Row style={{ padding: '10px 20px' }}>
|
||||
<Col span={6} style={{ lineHeight: '30px' }}>
|
||||
<Col span={8} style={{ lineHeight: '30px' }}>
|
||||
{(option as any)?.label || '文字'}:
|
||||
</Col>
|
||||
<Col span={18}>
|
||||
<Col span={16}>
|
||||
<Switch
|
||||
checked={props.current.props[(option as any).receive] || ''}
|
||||
onChange={(checked) => {
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-07-07 14:31:20
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-08-03 10:45:52
|
||||
* @LastEditTime: 2021-08-05 15:10:23
|
||||
* @FilePath: \dooringx\packages\dooringx-example\src\plugin\formTypes.ts
|
||||
*/
|
||||
export interface FormBaseType {
|
||||
@@ -10,14 +10,12 @@ export interface FormBaseType {
|
||||
}
|
||||
export interface FormInputType extends FormBaseType {
|
||||
label: string;
|
||||
text: string;
|
||||
}
|
||||
export interface FormActionButtonType {}
|
||||
export interface FormAnimateControlType {}
|
||||
|
||||
export interface FormSwitchType extends FormBaseType {
|
||||
label: string;
|
||||
value: boolean;
|
||||
}
|
||||
export interface FormMap {
|
||||
input: FormInputType;
|
||||
|
@@ -2,9 +2,41 @@
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-07-07 14:22:51
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-07-09 13:52:51
|
||||
* @LastEditTime: 2021-08-05 14:53:12
|
||||
* @FilePath: \dooringx\packages\dooringx-example\src\plugin\functionMap\index.ts
|
||||
*/
|
||||
import { FunctionCenterType } from 'dooringx-lib/dist/core/functionCenter';
|
||||
|
||||
export const functionMap: FunctionCenterType = {};
|
||||
export const functionMap: FunctionCenterType = {
|
||||
上下文转对象: {
|
||||
fn: (ctx, next, _config, args) => {
|
||||
const arr = args['_sk'];
|
||||
const key = args['_r'];
|
||||
const param: Record<string, any> = {};
|
||||
arr.forEach((v: string) => {
|
||||
param[v] = ctx[v];
|
||||
});
|
||||
ctx[key] = param;
|
||||
console.log(ctx);
|
||||
next();
|
||||
},
|
||||
config: [
|
||||
{
|
||||
name: '输入要获取的上下文',
|
||||
data: ['ctx'],
|
||||
options: {
|
||||
receive: '_sk',
|
||||
multi: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '输入要生成的上下文',
|
||||
data: ['ctx'],
|
||||
options: {
|
||||
receive: '_r',
|
||||
multi: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-02-27 21:33:36
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-08-03 23:21:01
|
||||
* @LastEditTime: 2021-08-05 10:54:22
|
||||
* @FilePath: \dooringx\packages\dooringx-example\src\plugin\index.tsx
|
||||
*/
|
||||
|
||||
@@ -12,6 +12,7 @@ import { ContainerOutlined, HighlightOutlined } from '@ant-design/icons';
|
||||
import commandModules from './commanderModules';
|
||||
import { functionMap } from './functionMap';
|
||||
import { Formmodules } from './formComponentModules';
|
||||
import InputCo from './registComponents/inputCo';
|
||||
|
||||
const LeftRegistMap: LeftRegistComponentMapItem[] = [
|
||||
{
|
||||
@@ -21,6 +22,12 @@ const LeftRegistMap: LeftRegistComponentMapItem[] = [
|
||||
displayName: '按钮',
|
||||
urlFn: () => import('./registComponents/button'),
|
||||
},
|
||||
{
|
||||
type: 'basic',
|
||||
component: 'input',
|
||||
img: 'icon-anniu',
|
||||
displayName: '输入框',
|
||||
},
|
||||
];
|
||||
|
||||
export const defaultConfig: Partial<InitConfig> = {
|
||||
@@ -38,7 +45,9 @@ export const defaultConfig: Partial<InitConfig> = {
|
||||
customRender: <div>我是自定义渲染</div>,
|
||||
},
|
||||
],
|
||||
initComponentCache: {},
|
||||
initComponentCache: {
|
||||
input: { component: InputCo },
|
||||
},
|
||||
rightRenderListCategory: [
|
||||
{
|
||||
type: 'style',
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-07-07 14:35:38
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-08-03 11:01:06
|
||||
* @LastEditTime: 2021-08-05 15:10:31
|
||||
* @FilePath: \dooringx\packages\dooringx-example\src\plugin\registComponents\button.tsx
|
||||
*/
|
||||
|
||||
@@ -102,14 +102,12 @@ const MButton = new ComponentItemFactory(
|
||||
createPannelOptions<FormMap, 'input'>('input', {
|
||||
receive: 'text',
|
||||
label: '文字',
|
||||
text: 'yehuozhili',
|
||||
}),
|
||||
],
|
||||
fn: [
|
||||
createPannelOptions<FormMap, 'switch'>('switch', {
|
||||
receive: 'op1',
|
||||
label: '改变文本函数',
|
||||
value: false,
|
||||
}),
|
||||
],
|
||||
animate: [createPannelOptions<FormMap, 'animateControl'>('animateControl', {})],
|
||||
|
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-08-05 10:50:57
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-08-05 15:10:46
|
||||
* @FilePath: \dooringx\packages\dooringx-example\src\plugin\registComponents\inputCo.tsx
|
||||
*/
|
||||
|
||||
import { Input } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import { ComponentItemFactory, createPannelOptions, UserConfig } from 'dooringx-lib';
|
||||
import { FormMap } from '../formTypes';
|
||||
import { IBlockType } from '../../../../dooringx-lib/dist/core/store/storetype';
|
||||
import Store from '../../../../dooringx-lib/dist/core/store';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
interface InputProps {
|
||||
data: IBlockType;
|
||||
context: string;
|
||||
store: Store;
|
||||
config: UserConfig;
|
||||
}
|
||||
|
||||
const InputTemp = (pr: InputProps) => {
|
||||
const { props } = pr.data;
|
||||
const data = pr.data;
|
||||
const dataCenter = pr.config.getDataCenter();
|
||||
const eventCenter = pr.config.getEventCenter();
|
||||
|
||||
const [value, setValue] = useState('');
|
||||
const [err, setErr] = useState('');
|
||||
useEffect(() => {
|
||||
let unregist = () => {};
|
||||
if (props.op1) {
|
||||
const functionCenter = eventCenter.getFunctionCenter();
|
||||
unregist = functionCenter.register(
|
||||
`${pr.data.id}+验证已填函数`,
|
||||
async (_ctx, next, _config, _args: any, _eventList, _iname) => {
|
||||
if (value === '') {
|
||||
setErr(props.warnning);
|
||||
} else {
|
||||
setErr('');
|
||||
next();
|
||||
}
|
||||
},
|
||||
[
|
||||
{
|
||||
name: '验证已填函数',
|
||||
data: [],
|
||||
options: {
|
||||
receive: '_changeval',
|
||||
multi: false,
|
||||
},
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
return () => {
|
||||
unregist();
|
||||
};
|
||||
}, [value, props.warnning, props.op1]);
|
||||
|
||||
useEffect(() => {
|
||||
let unregist = () => {};
|
||||
if (props.op2) {
|
||||
const functionCenter = eventCenter.getFunctionCenter();
|
||||
unregist = functionCenter.register(
|
||||
`${pr.data.id}+获取输入数据`,
|
||||
async (ctx, next, _config, args: any, _eventList, _iname) => {
|
||||
const key = args['_changeval'][0];
|
||||
ctx[key] = value;
|
||||
next();
|
||||
},
|
||||
[
|
||||
{
|
||||
name: '获取数据至上下文',
|
||||
data: ['ctx'],
|
||||
options: {
|
||||
receive: '_changeval',
|
||||
multi: false,
|
||||
},
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
return () => {
|
||||
unregist();
|
||||
};
|
||||
}, [value, props.op2]);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
zIndex: data.zIndex,
|
||||
width: data.width,
|
||||
height: data.height,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
value={value}
|
||||
type={props.type}
|
||||
placeholder={props.placeholder}
|
||||
style={{ height: 'calc( 100% - 20px )' }}
|
||||
onChange={(e) => {
|
||||
setValue(e.target.value);
|
||||
}}
|
||||
></Input>
|
||||
|
||||
<div style={{ height: '20px', color: 'red', fontSize: '12px' }}>{err}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const InputCo = new ComponentItemFactory(
|
||||
'input',
|
||||
'输入组件',
|
||||
{
|
||||
style: [
|
||||
createPannelOptions<FormMap, 'input'>('input', {
|
||||
receive: 'placeholder', //用于发送回的props,必传 ,跨组件传递需要指定额外字
|
||||
label: '文本',
|
||||
}),
|
||||
createPannelOptions<FormMap, 'input'>('input', {
|
||||
receive: 'warnning', //用于发送回的props,必传 ,跨组件传递需要指定额外字
|
||||
label: '验证消息',
|
||||
}),
|
||||
],
|
||||
fn: [
|
||||
createPannelOptions<FormMap, 'switch'>('switch', {
|
||||
receive: 'op1',
|
||||
label: '开启验证函数',
|
||||
}),
|
||||
createPannelOptions<FormMap, 'switch'>('switch', {
|
||||
receive: 'op2',
|
||||
label: '开启获取文本函数',
|
||||
}),
|
||||
],
|
||||
animate: [createPannelOptions<FormMap, 'animateControl'>('animateControl', {})],
|
||||
actions: [createPannelOptions<FormMap, 'actionButton'>('actionButton', {})],
|
||||
},
|
||||
{
|
||||
syncList: ['synckey'],
|
||||
props: {
|
||||
type: 'text',
|
||||
placeholder: '请输入',
|
||||
warnning: '输入框不可为空',
|
||||
op1: false,
|
||||
op2: false,
|
||||
},
|
||||
width: 200,
|
||||
height: 55,
|
||||
},
|
||||
(data, context, store, config) => {
|
||||
return <InputTemp data={data} context={context} store={store} config={config}></InputTemp>;
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
export default InputCo;
|
@@ -151,6 +151,8 @@ MIT
|
||||
|
||||
## Todo
|
||||
|
||||
动画部分重构
|
||||
|
||||
函数部分重构
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user