跳到主要内容

子表单场景指南

前言

子表单场景用于处理一对多的数据录入需求,例如商品分类表单中需要录入多个商品信息,每个商品包含多个字段(如商品名称、价格等)。为了高效管理数据,通常将分类和商品分别存储在不同的表中,并通过关联关系进行绑定。

在页面提交时,需要完成以下操作:

  1. 更新主表数据
  2. 新增、更新或删除子表数据
  3. 更新主表与子表之间的关联关系

由于涉及多次数据库交互,建议使用 云函数 来实现这一逻辑,前端只需调用云函数即可完成数据更新。

实现思路

子表单场景的实现可分为以下步骤:

  1. 处理子表单数据
    • 获取新增的子表数据
    • 获取需要更新的子表数据
    • 获取需要删除的子表数据
    • 更新子表数据
  2. 更新主表数据
    • 更新主表数据
    • 更新主表与子表的关联关系

云函数开发

新建云函数

进入 云函数 模块,新建名为 subTable-management 的云函数,并初始化项目:

npm init

npm install @cloudbase/node-sdk

编写代码

云函数需要接收以下参数:

  • mainName:主表数据模型名称
  • subCode:子表在主表中的编码
  • subName:子表数据模型名称
  • mainData:主表数据
  • subData:子表数据
  • subOldData:子表初始数据

核心逻辑

  1. 对比子表数据:通过 diffSubData 函数比对 子表初始数据子表当前数据,获取新增、更新和删除的数据。
  2. 执行子表操作:通过 executeSubTableOperations 方法执行子表数据的增删改操作。
  3. 更新主表数据:更新主表数据及其与子表的关联关系。

代码框架如下:

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)

字段名类型描述
namestring分类名称
splb关联关系(一对多)关联的商品列表

商品(products)

字段名类型描述
namestring商品名称
pricenumber商品价格
ssfl关联关系关联的商品分类

其中 splbssfl 字段类型为 关联关系 相互关联

新增应用

新建一个空白应用,通过模板快速生成「表格与表单页」,数据模型选择 商品分类(categories)

修改编辑页

进入编辑页面,由于表单容器绑定数据源并不能拿到子表完整数据,所以这里需要修改表单容器的数据源

页面新建内置数据表查询

在当前页面新增一个「内置数据表查询」方法

  1. 配置数据表为:商品分类(categories)
  2. 触发方式为:入参变化时自动执行
  3. 查询条件为:数据标识 等于 $w.page.dataset.params._id(url传过来的_id)
  4. 关联表查询选择 (对象)勾选 返回商品列表关联表

此时点击「运行」按钮可以看到数据中 splb字段返回了完整的商品列表数据

修改表单容器数据源

修改表单容器的数据源为:表达式

切换时会提示 「此操作将会重新生成/清空表单组件,是否需要重新生成/清空?」,选择

表达式内容为「内置数据表查询」结果

$w.page.dataset.params.formType === 'create' ? {} : $w.query1.data

修改商品列表组件

商品列表 组件默认是 下拉框,这里我们修改为 数组嵌套表单 组件

  1. 修改 嵌套表单模板对象数组(表格)
  2. 修改 绑定字段splb
  3. 添加子表字段:单行文本(名称)和 数字输入(价格)

  1. 修改 单行文本数字输入绑定字段标题 属性

修改提交事件

接下来查看「表单容器」的提交事件,其中调用了「数据源方法」进行更新数据

此时我们需要将其改成上章节新增的 云函数 去完成数据入库

因此我们切换「调用数据源方法」为「调用云函数方法」,并写下如下脚本,即可完成主子表的数据更新,云函数参数参考 上一章节

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.remoteValueform1 表单容器 组件的初始值

总结

通过云函数和页面开发的结合,可以高效实现子表单场景的数据管理。云函数负责处理复杂的数据库操作,前端只需调用云函数即可完成数据更新,确保逻辑清晰且性能优化。