mirror of
https://github.com/zhigang1992/form-render.git
synced 2026-06-13 09:14:41 +08:00
166 lines
3.9 KiB
JavaScript
166 lines
3.9 KiB
JavaScript
import getField from './getField';
|
||
import resolve from './resolve';
|
||
import subFieldGenerator from './subFieldGenerator';
|
||
|
||
// 对于数组或对象类型,获取其子集schema
|
||
function getSubSchemas(schema = {}) {
|
||
const {
|
||
// object subset
|
||
properties,
|
||
// array subset
|
||
items,
|
||
column,
|
||
// as subset's parent
|
||
...$parent
|
||
} = schema;
|
||
const { type } = $parent;
|
||
// no subset
|
||
if (!properties && !items) {
|
||
return [];
|
||
}
|
||
let children = {};
|
||
if (type === 'object') {
|
||
children = properties;
|
||
}
|
||
if (type === 'array') {
|
||
children = [].concat(items);
|
||
}
|
||
return Object.keys(children).map(name => ({
|
||
schema: children[name],
|
||
name,
|
||
column,
|
||
// parent propsSchema
|
||
$parent,
|
||
}));
|
||
}
|
||
|
||
function getBasicProps(settings, materials) {
|
||
const {
|
||
schema,
|
||
name = '',
|
||
$parent = {},
|
||
column,
|
||
displayType,
|
||
showDescIcon,
|
||
showValidate,
|
||
readOnly, // 添加全局控制只读模式
|
||
formData,
|
||
} = settings;
|
||
// 目前做了处理的`uiSchema`参数
|
||
const {
|
||
'ui:className': className,
|
||
'ui:options': options = {},
|
||
'ui:hidden': hidden,
|
||
'ui:disabled': disabled,
|
||
'ui:width': width,
|
||
'ui:readonly': readonly,
|
||
'ui:extraButtons': extraButtons = [],
|
||
'ui:dependShow': dependShow,
|
||
'ui:action': action,
|
||
} = schema;
|
||
const { required = [] } = $parent;
|
||
const { generated: widgets, customized: fields } = materials;
|
||
// 标准化属性模型
|
||
// 除了value和onChange为动态值这里不处理
|
||
let basicProps = {
|
||
name,
|
||
schema,
|
||
column,
|
||
displayType,
|
||
showDescIcon,
|
||
showValidate,
|
||
options, // 所有特定组件规则,addable等规则TODO
|
||
hidden,
|
||
required: required.indexOf(name) !== -1,
|
||
disabled: disabled,
|
||
readonly: readOnly || readonly, // 前者全局的,后者单个ui的
|
||
width,
|
||
widgets,
|
||
fields,
|
||
formData,
|
||
};
|
||
// 假如有表达式来决定显示的场景,才传入dependShow,formData
|
||
if (dependShow) {
|
||
basicProps = { ...basicProps, dependShow };
|
||
}
|
||
if (className) {
|
||
basicProps = { ...basicProps, className };
|
||
}
|
||
if (action) {
|
||
basicProps = { ...basicProps, action };
|
||
}
|
||
// 子集的属性
|
||
const subItems = {};
|
||
const subSchemas = getSubSchemas(schema);
|
||
subSchemas.forEach(subSchema => {
|
||
const { name: _name, schema: _schema = {} } = subSchema;
|
||
subItems[_name] = {
|
||
field: getField(_schema, materials),
|
||
props: getBasicProps(
|
||
{
|
||
...subSchema,
|
||
column,
|
||
displayType,
|
||
showDescIcon,
|
||
showValidate,
|
||
readOnly,
|
||
formData,
|
||
},
|
||
materials
|
||
),
|
||
};
|
||
});
|
||
if (['array', 'object'].indexOf(schema.type) >= 0) {
|
||
// 传入name和Field(如果重定义Field的话)及其配置信息(如onChange等)
|
||
basicProps.getSubField = o => {
|
||
// getSchemaData(schema)
|
||
const { field, props, column: c } = subItems[o.name] || subItems[0] || {};
|
||
return subFieldGenerator({
|
||
...field,
|
||
column: c,
|
||
props: {
|
||
...props,
|
||
name: o.name,
|
||
rootValue: o.rootValue,
|
||
},
|
||
})(o);
|
||
};
|
||
if (schema.type === 'array' && schema.items) {
|
||
// 将数组uiSchema配置里面的抽离出来使用
|
||
basicProps.extraButtons = extraButtons;
|
||
// 数组新增的默认值
|
||
if (subSchemas && subSchemas[0]) {
|
||
basicProps.newItem = resolve(subSchemas[0].schema);
|
||
}
|
||
}
|
||
}
|
||
return basicProps;
|
||
}
|
||
|
||
/**
|
||
* schema + materials --> parse --> Field + props
|
||
* schema {
|
||
* propsSchema,
|
||
* uiSchema,
|
||
* data,
|
||
* name,
|
||
* }
|
||
* materials {
|
||
* // 根据 Widget 生成的 Field
|
||
* generated,
|
||
* // 自定义的 Field
|
||
* customized,
|
||
* // 字段 type 与 widgetName 的映射关系
|
||
* mapping,
|
||
* }
|
||
*/
|
||
const parse = (settings = {}, materials) => {
|
||
const { schema = {} } = settings;
|
||
return {
|
||
Field: getField(schema, materials).Field,
|
||
props: getBasicProps(settings, materials),
|
||
};
|
||
};
|
||
|
||
export default parse;
|