在使用choerodon-ui组件库中的Form组件做查询表单时,使用其自带的dataSet数据源进行开发,根据dataSet中查询字段来引入如TextField、Select、DatePicker等组件,还要进行样式排版很麻烦,所以写一个QueryMoreBar组件对其进行了封装,利用了dataSet中查询字段field对象属性的中type字段进行判断该引入哪个表单项组件
使用方式
先定义一个dataSet数据集
const FormDS = (): DataSetProps => {
return {
queryDataSet: new DataSet({
autoCreate: true,
fields: [
{ name: "name", type: FieldType.string, label: "姓名" },
{
name: "sex",
type: FieldType.string,
label: "年龄",
options: new DataSet({
paging: false,
data: [{ value: "F", meaning: "女" }, { value: "M", meaning: "男" }]
})
},
{
name: "email",
type: FieldType.email,
label: "邮箱"
},
{
name: "phone",
type: FieldType.string,
label: "联系方式"
},
{
name: "dadeline",
type: FieldType.month,
label: "截至日期"
}
]
})
};
};
复制代码
然后,传入QueryMoreBar的几个必须属性props,dataSet、queryFunction等
<QueryMoreBar
dataSet={formDS}
queryFunction={handleQuery}
queryFieldsLimit={2}
labelWidth={80}
/>
复制代码
运行yarn start
命令就可以看到页面了
QueryMoreBar组件
属性props
- dataSet:DataSet类型,必传
- queryFunction:回调函数,必传
- buttons:ReactElement类型的数组,可省略
- queryFieldsLimit:number类型,一行几列,默认4,可省略
- labelWidth:number类型,默认100,可省略
获取查询表单项
在choerodon-ui里的Form组件在绑定数据源dataSet的情况下,是不需要对其每个子元素做受控处理的,只需要给每个表单项子元素的name属性给予正确的值即可,但是还是需要引入所需要的表单项组件
这里写入一个方法getQueryFields
自动根据dataSet里field属性数组对象里的type值进行判断需要引入哪种类型的表单项组件
// 获取查询列
function getQueryFields(dataSet: DataSet): any {
const { queryDataSet } = dataSet;
const result: any = [];
if (queryDataSet) {
const { fields } = queryDataSet;
return [...fields.entries()].reduce((list, [name, field]) => {
if (!field.get("bind")) {
const props = { key: name, name };
list.push(cloneElement(getEditorByField(field), props));
}
return list;
}, result);
}
}
复制代码
其中getEditorByField
返回的是组件
// 根据type匹配搜索框
function getEditorByField(field: any): any {
const lookupCode = field.get("lookupCode");
const lookupUrl = field.get("lookupUrl");
const lovCode = field.get("lovCode");
const multiLine = field.get("multiLine");
const { type } = field;
if (
lookupCode ||
isString(lookupUrl) ||
(type !== FieldType.object && (lovCode || field.options))
) {
return <Select />;
}
if (lovCode) return <Lov />;
if (multiLine) return <Output />;
switch (type) {
case FieldType.boolean:
return <CheckBox />;
case FieldType.number:
return <NumberField />;
case FieldType.currency:
return <Currency />;
case FieldType.date:
return <DatePicker />;
case FieldType.dateTime:
return <DateTimePicker />;
case FieldType.time:
return <TimePicker />;
case FieldType.week:
return <WeekPicker />;
case FieldType.month:
return <MonthPicker />;
case FieldType.year:
return <YearPicker />;
case FieldType.intl:
return <IntlField />;
case FieldType.email:
return <EmailField />;
case FieldType.url:
return <UrlField />;
case FieldType.color:
return <ColorPicker />;
case FieldType.string:
return <TextField />;
default:
return <TextField />;
}
}
复制代码
完成Form表单
拿到表单项数组之后,接下来就是完成Form表单了,根据queryFieldsLimit来限制表单项的显示和排版
const QueryMoreBar: React.FC<QueryMoreBarProps> = ({
dataSet,
queryFunction,
buttons,
queryFieldsLimit = 4,
labelWidth = 100
}: QueryMoreBarProps) => {
const [hidden, setHidden] = useState(true);
// 查询的字段数组
const queryFields = getQueryFields(dataSet);
// 更多查询
const handleToggle = () => {
setHidden(!hidden);
};
const { queryDataSet } = dataSet;
// 校验通过则返回调用查询函数
const query = async () => {
if (queryDataSet) {
return (await queryDataSet.validate()) && queryFunction();
}
};
return (
<div>
{queryDataSet ? (
<div
style={{
display: "flex",
marginBottom: "3px",
alignItems: "flex-start"
}}
>
<Form
style={{ flex: "auto" }}
columns={queryFieldsLimit}
dataSet={queryDataSet}
labelWidth={labelWidth}
useColon
onKeyDown={(e: any) => {
if (e.keyCode === 13) return query();
}}
>
{hidden ? queryFields.slice(0, queryFieldsLimit) : queryFields}
</Form>
<div
style={{
marginTop: "10px",
flexShrink: 0,
display: "flex",
alignItems: "center"
}}
>
{queryFields.length > queryFieldsLimit && (
<Button onClick={handleToggle}>
{hidden ? "更多查询" : "收起查询"}
</Button>
)}
<Button
onClick={() => {
if (queryDataSet.current) queryDataSet.current.reset();
dataSet.fireEvent("queryBarReset", {
dataSet,
queryFields
});
}}
>
重置
</Button>
<Button color={ButtonColor.primary} onClick={query}>
查询
</Button>
</div>
</div>
) : null}
{buttons && buttons.length ? (
<div style={{ marginBottom: 4 }}>{buttons}</div>
) : null}
</div>
);
};
复制代码
最后,完成QueryMoreBar查询表单的封装,完整的代码地址QueryMoreBar
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END