From 90a4ce0285907caab90dd271a39172baaeccd8b6 Mon Sep 17 00:00:00 2001 From: hufeixiong <673632758@qq.com> Date: Thu, 5 Aug 2021 15:13:57 +0800 Subject: [PATCH] add form submit example --- packages/dooringx-doc/src/docs/4.4.md | 21 +++ .../src/plugin/formComponents/switch.tsx | 6 +- .../dooringx-example/src/plugin/formTypes.ts | 4 +- .../src/plugin/functionMap/index.ts | 36 +++- .../dooringx-example/src/plugin/index.tsx | 13 +- .../src/plugin/registComponents/button.tsx | 4 +- .../src/plugin/registComponents/inputCo.tsx | 161 ++++++++++++++++++ packages/dooringx-lib/README.md | 2 + 8 files changed, 234 insertions(+), 13 deletions(-) create mode 100644 packages/dooringx-doc/src/docs/4.4.md create mode 100644 packages/dooringx-example/src/plugin/registComponents/inputCo.tsx diff --git a/packages/dooringx-doc/src/docs/4.4.md b/packages/dooringx-doc/src/docs/4.4.md new file mode 100644 index 0000000..01d43a4 --- /dev/null +++ b/packages/dooringx-doc/src/docs/4.4.md @@ -0,0 +1,21 @@ +--- +title: 表单验证提交思路 +sTitle: 常见问题 +order: 20 +--- + +表单验证提交有非常多的做法,因为数据全部是联通的,或者直接写个表单组件也可以。 + +在不使用表单组件时,简单的做法是为每个输入组件做个验证函数与提交函数。 + +这样是否验证就取决于用户的选取,而抛出的输入可以让用户选择放到哪,并由用户去命名变量。 + +在点击提交按钮时,调用所有组件的验证函数与提交函数,使其抛给上下文,再通过上下文聚合函数聚合成对象,最后可以通过发送函数发送给对应后端,从而完成整个流程。你可以在example中试下这个demo。 + +如果操作人员能看懂后端提供的接口文档,那么就可以让操作人员自己通过命名来拼出后端想要的字段。 + +如果不需要文档,那么某些值也可以在开发时写死。 + +另外的做法是可以专门写个提交按钮,固定了参数,以及部分规则,比如规定在页面中的所有表单都会被收集提交。 + +那么我们可以利用数据源,将所有表单输出内容自动提交给数据源,最后的提交按钮按数据源规定格式的key提取,发送给后端。 \ No newline at end of file diff --git a/packages/dooringx-example/src/plugin/formComponents/switch.tsx b/packages/dooringx-example/src/plugin/formComponents/switch.tsx index 5d7eb23..019a530 100644 --- a/packages/dooringx-example/src/plugin/formComponents/switch.tsx +++ b/packages/dooringx-example/src/plugin/formComponents/switch.tsx @@ -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 ( - + {(option as any)?.label || '文字'}: - + { diff --git a/packages/dooringx-example/src/plugin/formTypes.ts b/packages/dooringx-example/src/plugin/formTypes.ts index 7526054..21e72cc 100644 --- a/packages/dooringx-example/src/plugin/formTypes.ts +++ b/packages/dooringx-example/src/plugin/formTypes.ts @@ -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; diff --git a/packages/dooringx-example/src/plugin/functionMap/index.ts b/packages/dooringx-example/src/plugin/functionMap/index.ts index 9e90d00..1afdc6c 100644 --- a/packages/dooringx-example/src/plugin/functionMap/index.ts +++ b/packages/dooringx-example/src/plugin/functionMap/index.ts @@ -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 = {}; + 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, + }, + }, + ], + }, +}; diff --git a/packages/dooringx-example/src/plugin/index.tsx b/packages/dooringx-example/src/plugin/index.tsx index fae7ee2..0a7ea24 100644 --- a/packages/dooringx-example/src/plugin/index.tsx +++ b/packages/dooringx-example/src/plugin/index.tsx @@ -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 = { @@ -38,7 +45,9 @@ export const defaultConfig: Partial = { customRender:
我是自定义渲染
, }, ], - initComponentCache: {}, + initComponentCache: { + input: { component: InputCo }, + }, rightRenderListCategory: [ { type: 'style', diff --git a/packages/dooringx-example/src/plugin/registComponents/button.tsx b/packages/dooringx-example/src/plugin/registComponents/button.tsx index 649949d..6ff2c06 100644 --- a/packages/dooringx-example/src/plugin/registComponents/button.tsx +++ b/packages/dooringx-example/src/plugin/registComponents/button.tsx @@ -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('input', { receive: 'text', label: '文字', - text: 'yehuozhili', }), ], fn: [ createPannelOptions('switch', { receive: 'op1', label: '改变文本函数', - value: false, }), ], animate: [createPannelOptions('animateControl', {})], diff --git a/packages/dooringx-example/src/plugin/registComponents/inputCo.tsx b/packages/dooringx-example/src/plugin/registComponents/inputCo.tsx new file mode 100644 index 0000000..492d27a --- /dev/null +++ b/packages/dooringx-example/src/plugin/registComponents/inputCo.tsx @@ -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 ( +
+ { + setValue(e.target.value); + }} + > + +
{err}
+
+ ); +}; + +const InputCo = new ComponentItemFactory( + 'input', + '输入组件', + { + style: [ + createPannelOptions('input', { + receive: 'placeholder', //用于发送回的props,必传 ,跨组件传递需要指定额外字 + label: '文本', + }), + createPannelOptions('input', { + receive: 'warnning', //用于发送回的props,必传 ,跨组件传递需要指定额外字 + label: '验证消息', + }), + ], + fn: [ + createPannelOptions('switch', { + receive: 'op1', + label: '开启验证函数', + }), + createPannelOptions('switch', { + receive: 'op2', + label: '开启获取文本函数', + }), + ], + animate: [createPannelOptions('animateControl', {})], + actions: [createPannelOptions('actionButton', {})], + }, + { + syncList: ['synckey'], + props: { + type: 'text', + placeholder: '请输入', + warnning: '输入框不可为空', + op1: false, + op2: false, + }, + width: 200, + height: 55, + }, + (data, context, store, config) => { + return ; + }, + true +); + +export default InputCo; diff --git a/packages/dooringx-lib/README.md b/packages/dooringx-lib/README.md index 720cf39..b94b61b 100644 --- a/packages/dooringx-lib/README.md +++ b/packages/dooringx-lib/README.md @@ -151,6 +151,8 @@ MIT ## Todo +动画部分重构 + 函数部分重构