跳到主要内容

control 联动控制

vcontrol 显隐控制

介绍

对于表单而言,我们经常会通过某些表单项的操作,触发另一些表单项的显隐。

Drip-Form 为每个表单项内置了vcontrol字段,用于表单项之间产生UI 显隐的控制关联。

该字段配置于unitedSchema.json中:

unitedSchema.json
{
"validateTime": "submit",
"type": "object",
"theme": "drip-theme",
"schema": [
{
"title": "开关",
"type": "string",
"ui": {
"type": "switch"
},
"fieldKey": "switchItem"
},
{
"type": "string",
"title": "自定义组件",
"ui": {
"type": "custom2",
"vcontrol": "return props.formData.switchItem"
},
"fieldKey": "custom2"
}
]
}

我们为 custom2 添加了 vcontrol 字段,并配置了一个 return 语句。 该语句在执行之后会返回一个 Boolean 值,用来触发被控制字段的显隐,返回 true 则展示 custom2表单项,否则隐藏该项。

注意

vcontrol仅支持以字符串的形式书写函数体,如果你需要复杂的显隐处理,请使用函数占位符处理。

vcontrol基于new Function实现,因此在书写的函数体内,我们可以使用如下三个参数:

参数类型说明
formDataObject当前最新的表单数据
fieldKeystring当前操作表单项的 fieldKey
fieldDataObject当前操作表单项的数据

在上文中,我们使用 props.formData.switchItem 获取到了switch 开关 当前的状态,并根据其是否开启的来判断是否展示 custom2 自定义组件。

完整示例

Form.jsx
import React, { Component, memo, useState } from 'react'
import DripForm from '@jdfed/drip-form'
import dripTheme from '@jdfed/drip-form-theme-antd'
import unitedSchema from './unitedComponents.json'
import '@jdfed/drip-form-theme-antd/dist/index.css'
import '@jdfed/drip-form/dist/index.css'

const CustomField1 = memo(() => {
const [count, setCount] = useState(0)
return (
<div>
<p>You clicked {count} times</p>
<div onClick={() => setCount(count + 1)}>Click me</div>
</div>
)
})

const customComponents = {
custom1: CustomField1,
}

export default class Form extends Component {
render() {
return (
<div>
<DripForm
unitedSchema={unitedSchema}
uiComponents={{ 'drip-theme': dripTheme }}
customComponents={customComponents}
/>
</div>
)
}
}
图片加载出错

onChange 数据联动

除了表单间的显隐控制联动,我们通常还会因为某些项的修改而触发另一些数据的变更。

在 drip-form 中,我们可以在 unitedSchema 中为需要的表单项配置 onChange 字段:

unitedSchema.json
{
"validateTime": "submit",
"type": "object",
"theme": "drip-theme",
"schema": [
{
"title": "开关",
"type": "string",
"ui": {
"type": "switch",
"onChange": "val && dispatch({type: 'setData',action:{set:{custom2: '触发了开关开启'}}})"
},
"fieldKey": "switchItem"
},
{
"type": "string",
"title": "自定义组件",
"ui": {
"type": "custom2"
},
"fieldKey": "custom2"
}
]
}

vcontrol一样,onChange字段同样接收一个字符串类型的函数体,其原理也是基于new FunctiononChange允许我们在函数体内使用五个参数:

参数类型说明
valany一般情况下,返回修改过后的表单的 e.target.value,如果无法获取到,则返回 e
dispatch(options: Object) => void触发表单修改的函数
fieldKeystring当前触发表单项的 key 值
prevFieldDataany修改之前该项的表单数据
fieldDataany修改过后该项的表单数据,避免 val 获取到为 undefined 的问题
注意

此处参数中的 filedKey 需要配置为待修改的表单 key 值,在上文的unitedSchema中,我们配置成了 custom2,因此会触发该表单项的修改。

如果我们是触发deleteFormData操作,则只需配置为{type: 'deleteFormData', key: 'custom2'}即可。

如果你需要复杂的数据联动处理,请使用函数占位符处理。

control 全局控制

在考虑使用 control 监听全局变化前,请先阅读vontrol 控制显隐onChange 数据联动,如果这两者可以满足你的需求,请尽量不要使用 control,因为它可能会被触发而产生一些错误行为。

control 会监听全局的数据和 UI 变化,因此你可以在此执行更为复杂的监听。它作为props传入 drip-form 中:

Form.jsx
import React, { memo, useCallback } from 'react'
import DripForm from 'drip-form'

const onGlobalChange = useCallback(({ formData, dispatch }) => {
// 在这里执行操作
})

const Form = memo(() => {
return <DripForm
...
control={onGlobalChange}
/>
})

control支持四个参数:

参数类型说明
formDataobject当前表单数据
dispatch(options) => void触发表单修改的函数