表单中子表单常见场景的应用
在搭建宜搭应用的过程中,你可能会遇到以下这些问题。
- 子表单内如何设置自定义校验函数,当前输入的组件与当前行其他组件进行校验,如:批量出库时,出库数不得大于库存数
- 子表单内如何动态设置开启、关闭组件校验,如:满足某个条件时,当前行内某些组件开启、关闭必填校验
- 子表单内如何动态设置组件状态,如:满足某个条件时,当前行内某些组件状态设置为只读或者禁用
- 子表单内如何实现数据联动的效果
前提条件
本教程使用到宜搭部分基础功能,你可以先了解以下功能。
实现效果
子表单自定义校验

子表单动态设置校验

子表单动态设置组件状态

子表单内数据联动



实现步骤
子表单自定义校验
创建普遍表单页面
创建普通表单页面,详情请参考普通表单。

在画布区域拖入以下组件。
- 子表单:命名为子表单
- 下拉单选:命名为产品信息
- 数值:命名为库存数
- 数值:命名为出库数
配置自定义校验
将下述代码拷贝至页面 JS 面板中,注意修改代码中的唯一标识。

// 出库数自定义校验(出库数不得大于库存数)
// numberField_lonxsiwh 为子表单内库存数字段的唯一标识,请按需修改
export function validateRuleForOutbound(value) {
const { values } = this.item;
const inventoryCount = values.numberField_lonxsiwh || 0; // 获取库存数
return value <= inventoryCount;
}
出库数组件自定义函数中调用上述函数。

function validateRule(value) {
return this.validateRuleForOutbound(value);
}
保存页面

子表单动态设置校验
注意:此方式不会去掉必填的 * 标记,但有实际效果。
创建普遍表单页面
创建普通表单页面,详情请参考普通表单。

在画布区域拖入以下组件。
- 子表单:命名为子表单
- 单选:命名为是否开启产品信息校验
- 下拉单选:命名为产品信息
配置组件事件
将下述代码拷贝至页面 JS 面板中,注意修改代码中的唯一标识。

// 子表单动态设置校验(enableValid / disableValid)
export function onChange({ value }) {
if (value === '是') {
this.$('selectField_lonxsixa').enableValid();
} else {
this.$('selectField_lonxsixa').disableValid();
}
}
是否开启产品信息校验组件 onChange 绑定上述函数。

保存页面

子表单动态设置组件状态
创建普遍表单页面
创建普通表单页面,详情请参考普通表单。

在画布区域拖入以下组件。
- 子表单:命名为子表单
- 单选:命名为产品信息字段状态
- 选择配置
- 下拉单选:命名为产品信息
配置组件事件
将下述代码拷贝至页面 JS 面板中,注意修改代码中的唯一标识。

// 产品信息字段状态组件 onChange
export function onChange({ value }) {
this.$('selectField_lonxsiwo').setBehavior(value);
}
产品信息字段状态组件 onChange 绑定上述函数。

保存页面

子表单内数据联动
创建普遍表单页面
创建普通表单页面,详情请参考普通表单。

在画布区域拖入以下组件。
- 单行文本:命名为类型

在画布区域拖入以下组件。
- 下拉单选:命名为物品类型
- 配置【关联其他表单数据】
- 单行文本:命名为物品名称

在画布区域拖入以下组件。
- 子表单:命名为子表单
- 下拉单选:命名为物品类型
- 下拉单选:命名为物品名称
添加数据源


请求地址绑定下述变量。

`/${window.pageConfig.appType || window.g_config.appKey}/v1/form/searchFormDatas.json`
物品类型配置【关联其他表单数据】
将下述代码拷贝至页面 JS 面板中。

/**
* 子表单子组件添加选项
* @param formUuid: {String} 被关联表单的 formUuid
* @param relationFieldId: {String} 被关联字段的唯一标识
* @param searchFieldJson: {Object} 筛选条件
* @param tableFieldId: {String} 需要添加选项组件的子表单唯一标识
* @param fieldId: {String} 需要添加选项组件的唯一标识
* @param childFieldItems: {Array} 需要添加选项组件的行标识,不传或传空默认全部添加
* @param isUniq: {Boolean} 是否按选项值去重
*/
export function getTableSelectFieldDataSource(formUuid = '', relationFieldId = '', searchFieldJson = {}, tableFieldId = '', fieldId = '', childFieldItems = [], isUniq = false) {
const tableField = this.$(tableFieldId); // 获取子表单定义
// 如果未传 childFieldItems,默认获取子表单所有行
const items = _.isEmpty(childFieldItems) ? tableField.getItems() : childFieldItems;
this.dataSourceMap.getData.load({
formUuid,
pageSize: 100,
searchFieldJson: JSON.stringify(searchFieldJson),
}).then((res) => {
const { data = [] } = res;
const tableSelectField = data.map((item) => {
const { formData = {} } = item;
return {
text: formData[relationFieldId], // 显示值
value: formData[relationFieldId], // 选项值
};
});
items.forEach((item) => {
tableField.setComponentProps(item, fieldId, {
dataSource: isUniq ? _.uniqBy(tableSelectField, 'value') : tableSelectField, // 按选项值去重
});
});
}).catch(({ message }) => {
this.utils.toast({
title: message,
type: 'error',
});
});
}
页面初始化的时候我们就要对物品类型配置选项,所以 didMount 时需调用一下,注意修改表单 formUuid 和组件唯一标识,这里的FORM-8B5130A6967A4D4DA36F5EC3FF6D4B1CUD57
是物品类型表的 formUuid。

export function didMount() {
this.getTableSelectFieldDataSource(
'FORM-8B5130A6967A4D4DA36F5EC3FF6D4B1CUD57',
'textField_lz87gtfq',
{},
'tableField_lz88ervv',
'selectField_lz88ervw'
);
}
子表单新增一项时也需要调用一下,对新增行的物品类型配置选项,子表单新增一项绑定下述函数。

// 新增一项
export function onAddClick(newGroupId) {
// 为新增物品类型赋值选项
this.getTableSelectFieldDataSource(
'FORM-A98628AA71774B7EA636E8CB875508DD24K3',
'textField_lz87gtfq',
{},
'tableField_lz88ervv',
'selectField_lz88ervw',
[newGroupId]
);
}
物品名称配置【数据联动】
子表单 onChange 绑定下述函数,这里的FORM-C04CAE23888848A885997B5726AADF647LC9
是物品表的表单 formUuid。

// 子表单 onChange
export function onTableChange({ value, extra }) {
const { formGroupId, from, tableFieldId, fieldId, changes = {} } = extra || {};
// 必须,避免使用 updateItemValue 更新子表数据后,再次触发 onChange 陷入死循环
if (from === 'setItemValue') { return; };
const tableField = this.$(tableFieldId); // 获取子表单定义
if (fieldId && fieldId === 'selectField_lz88ervw') {
// 当前 onChange 字段是物品类型时为物品名称赋值选项
if (changes.value) {
this.getTableSelectFieldDataSource(
'FORM-43F11FA3281F485683EBBC684C658928O08P',
'textField_lz87hsan',
{
selectField_lz87hsam: changes.value,
},
tableFieldId,
'selectField_lz88ervx',
[formGroupId]
);
} else {
tableField.updateItemValue(formGroupId, {
selectField_lz88ervx: '',
}); // 清空选项值
tableField.setComponentProps(formGroupId, 'selectField_lz88ervx', {
dataSource: [],
}); // 清空 dataSource
}
}
}
物品名称 onVisibleChange 绑定下述函数,兼容详情页编辑。

// 下拉框是否显示(兼容详情页面编辑)
export function onVisibleChange(visible) {
const { id } = this.item; // 获取当前行的行标识
const type = this.$('selectField_lz88ervw').getValue(); // 获取物品类型的值
const dataSource = this.$('selectField_lz88ervx').props.dataSource; // 获取当前下拉选项的选项
if (visible && !this.utils.isSubmissionPage() && !_.isEmpty(type) && _.isEmpty(dataSource)) {
// 弹层显示且详情页且物品类型不为空且当前下拉没有选项时请求选项,节省资源
this.getTableSelectFieldDataSource(
'FORM-C04CAE23888848A885997B5726AADF647LC9',
'textField_lz87hsan',
{
selectField_lz87hsam: this.$('selectField_lz88ervw').getValue(),
},
'tableField_lz88ervv',
'selectField_lz88ervx',
[id]
);
}
}
保存页面

在线试玩
本文档对您是否有帮助?