子表单场景指南
前言
子表单场景用于处理一对多的数据录入需求,例如商品分类表单中需要录入多个商品信息,每个商品包含多个字段(如商品名称、价格等)。为了高效管理数据,通常将分类和商品分别存储在不同的表中,并通过关联关系进行绑定。
在页面提交时,需要完成以下操作:
- 更新主表数据
- 新增、更新或删除子表数据
- 更新主表与子表之间的关联关系
由于涉及多次数据库交互,建议使用 云函数 来实现这一逻辑,前端只需调用云函数即可完成数据更新。
实现思路
子表单场景的实现可分为以下步骤:
- 处理子表单数据
- 获取新增的子表数据
- 获取需要更新的子表数据
- 获取需要删除的子表数据
- 更新子表数据
- 更新主表数据
- 更新主表数据
- 更新主表与子表的关联关系
云函数开发
新建云函数
进入 云函数 模块,新建名为 subTable-management
的云函数,并初始化项目:
npm init
npm install @cloudbase/node-sdk
编写代码
云函数需要接收以下参数:
mainName
:主表数据模型名称subCode
:子表在主表中的编码subName
:子表数据模型名称mainData
:主表数据subData
:子表数据subOldData
:子表初始数据
核心逻辑
- 对比子表数据:通过
diffSubData
函数比对 子表初始数据 和 子表当前数据,获取新增、更新和删除的数据。 - 执行子表操作:通过
executeSubTableOperations
方法执行子表数据的增删改操作。 - 更新主表数据:更新主表数据及其与子表的关联关系。
代码框架如下:
const cloudbase = require('@cloudbase/node-sdk');
const app = cloudbase.init({
env: cloudbase.SYMBOL_CURRENT_ENV,
});
const models = app.models;
/**
* 处理主表与子表数据关系
* @param {string} mainName - 主表名称
* @param {string} subCode - 子表在主表中的编码
* @param {string} subName - 子表名称
* @param {object} mainData - 主表数据
* @param {array} subData - 子表当前数据
* @param {array} subOldData - 子表源数据
* @returns {Promise<object>} 处理结果
*/
exports.main = async function({
mainName,
subCode,
subName,
mainData,
subData,
subOldData
}) {
try {
// 1. 对比子表数据,获取增删改操作
const {
addData,
updateData,
deleteIds
} = diffSubData(subData, subOldData);
// 2. 执行子表数据的增删改操作
const subRes = await executeSubTableOperations(subName, addData, updateData, deleteIds);
// 3. 更新主表数据
// ...
return {
success: true,
message: '数据处理成功',
details: {
subRes,
res,
},
};
} catch (error) {
console.error('数据处理失败:', error);
throw new Error(`数据处理失败: ${error.message}`);
}
};
完整代码示例请参考:GitHub 示例
部署云函数
点击「保存并安装依赖」,即可完成云函数的部署
页面开发
新建数据模型
进入 数据模型 新建如下两个数据模型:
商品分类(categories)
字段名 | 类型 | 描述 |
---|---|---|
name | string | 分类名称 |
splb | 关联关系(一对多) | 关联的商品列表 |
商品(products)
字段名 | 类型 | 描述 |
---|---|---|
name | string | 商品名称 |
price | number | 商品价格 |
ssfl | 关联关系 | 关联的商品分类 |
其中 splb 和 ssfl 字段类型为 关联关系 相互关联
新增应用
新建一个空白应用,通过模板快速生成「表格与表单页」,数据模型选择 商品分类(categories)
修改编辑页
进入编辑页面,由于表单容器绑定数据源并不能拿到子表完整数据,所以这里需要修改表单容器的数据源
页面新建内置数据表查询
在当前页面新增一个「内置数据表查询」方法
- 配置数据表为:商品分类(categories)
- 触发方式为:入参变化时自动执行
- 查询条件为:数据标识 等于 $w.page.dataset.params._id(url传过来的_id)
- 关联表查询选择 (对象)勾选 返回商品列表关联表
此时点击「运行」按钮可以看到数据中 splb字段返回了完整的商品列表数据
修改表单容器数据源
修改表单容器的数据源为:表达式
切换时会提示 「此操作将会重新生成/清空表单组件,是否需要重新生成/清空?」,选择 否
表达式内容为「内置数据表查询」结果
$w.page.dataset.params.formType === 'create' ? {} : $w.query1.data
修改商品列表组件
商品列表 组件默认是 下拉框,这里我们修改为 数组嵌套表单 组件
- 修改 嵌套表单模板 为 对象数组(表格)
- 修改 绑定字段 为 splb
- 添加子表字段:单行文本(名称)和 数字输入(价格)
- 修改 单行文本 和 数字输入 的 绑定字段 和 标题 属性
修改提交事件
接下来查看「表单容器」的提交事件,其中调用了「数据源方法」进行更新数据
此时我们需要将其改成上章节新增的 云函数 去完成数据入库
因此我们切换「调用数据源方法」为「调用云函数方法」,并写下如下脚本,即可完成主子表的数据更新,云函数参数参考 上一章节
async () => {
await $w.cloud.callFunction({
name: 'subTable-management',
data: {
mainName: 'categories',
subCode: 'splb',
subName: 'products',
mainData: {
...$w.form1.value,
_id: $w.page.dataset.params._id
},
subData: $w.value?.splb || [],
subOldData: $w.form1.remoteValue?.splb || [],
},
});
};
⚠️ 注意:
mainData 中需要带上 _id
$w.form1.remoteValue
是 form1 表单容器 组件的初始值
总结
通过云函数和页面开发的结合,可以高效实现子表单场景的数据管理。云函数负责处理复杂的数据库操作,前端只需调用云函数即可完成数据更新,确保逻辑清晰且性能优化。