Geejing WebBuilder|主副表(主子表)联动标准配置

✅ 核心机制:主 Grid 监听 selectionchange(选中行变更)→ 取出主表主键 → 子Grid.load({params:{主键}}) 刷新明细,Geejing WebBuilder 原生标准写法,XWL 配置 + 服务端脚本一体。业务示例:订单(主)→订单明细(副)、合同→合同条款、项目→任务台账

一、前置准备(数据库 + 2 个后端 Action)

  1. 数据表设计
  • 主表:biz_order,主键 order_id
  • 副表:biz_order_item,外键 order_id(关联主表主键)
  1. 后端准备 2 个查询 action:
  • getOrderList:加载全部订单主表
  • getOrderItemList:接收参数order_id,查询该订单明细

二、完整可直接导入 XWL 源码(上下双 Grid,最常用)

swift 复制代码
module
{
  "cid":"mainSubOrderModule",
  "cls":"Wb.Module",
  "properties":{"cid":"mainSubOrderModule"},
  "events":{
    "initialize":"Wb.apply(app,{\n  onLoad(){\n    // 页面初始化加载主表\n    app.gridMain.load();\n  }\n});"
  },
  "items":[
    // ========== 主表Grid ==========
    {
      "cid":"gridMain",
      "cls":"Wb.Grid",
      "title":"订单主表",
      "url":xpath + "/actions&xaction=getOrderList",
      "columns":[
        {"text":"订单ID","fieldName":"order_id","width":120},
        {"text":"客户名称","fieldName":"cust_name"},
        {"text":"下单时间","fieldName":"create_time"}
      ],
      "events":{
        // ✅联动核心事件:selectionchange 选中行切换
        "selectionchange":`
          const row = this.selection;
          if(!row){
            // 取消选中:清空副表,防止旧数据残留
            app.gridSub.clear();
            return;
          }
          // 携带主表主键,刷新副表明细
          app.gridSub.load({
            params:{
              order_id: row.order_id
            }
          });
        `
      }
    },
    // ========== 副表(明细Grid) ==========
    {
      "cid":"gridSub",
      "cls":"Wb.Grid",
      "title":"订单明细",
      "url":xpath + "/actions&xaction=getOrderItemList",
      "columns":[
        {"text":"商品名称","fieldName":"goods_name"},
        {"text":"单价","fieldName":"price"},
        {"text":"数量","fieldName":"qty"},
        {"text":"金额","fieldName":"amt"}
      ]
    }
  ]
}

三、服务端 ServerScript(WebBuilder 内置脚本,直接复制)

ini 复制代码
let xaction = Params.xaction;
if(xaction === "getOrderList"){
  // 主表列表
  return Wb.db.query("select order_id,cust_name,create_time from biz_order");
}
if(xaction === "getOrderItemList"){
  let orderId = Params.order_id || "";
  // 按主表主键过滤明细,参数防注入使用?占位符
  return Wb.db.query("select goods_name,price,qty,amt from biz_order_item where order_id=?",[orderId]);
}

四、两种常用联动模式

模式 1:上下双 Grid(上面主、下面明细,上面选中自动刷下面)

👉 就是上面这份标准代码,90% 业务首选

  • 单选:this.selection 取单行
  • 多选场景:this.selections 数组,后端用 IN(...) 查询

模式 2:主表行展开嵌套子表(expand 展开行,不单独占页面)

适合不想上下布局,点展开箭头才加载明细:

php 复制代码
// 在gridMain配置 expand:true,expandRenderer渲染内嵌子Grid
"expandRenderer":`
  return Wb.render({
    cid:"innerSubGrid",
    cls:"Wb.Grid",
    url:xpath+"/actions&xaction=getOrderItemList",
    params:{order_id:data.order_id}
  })
`

五、高频踩坑点 & 最佳实践(Geejing WebBuilder 专属)

  1. **空选中必须 clear ()**取消行选中时执行app.gridSub.clear(),否则副表保留上次明细,造成数据混淆
  2. 主键类型严格一致 数字型主键不要传字符串,否则 SQL 匹配不到数据(1000 vs "1000"
  3. 新增 / 编辑明细联动 新增明细弹窗时,直接读取app.gridMain.selection.order_id自动回填外键,保存后执行app.gridSub.load()刷新明细
  4. 多选主子表
ini 复制代码
// selectionchange内多选写法
const rows = this.selections;
if(!rows.length){app.gridSub.clear();return;}
const ids = rows.map(r=>r.order_id).join(",");
app.gridSub.load({params:{idList:ids}});

后端 SQL:where order_id IN (?)5. 加载体验优化 大数据明细可增加 loading:app.gridSub.loading=true,加载完自动关闭

相关推荐
许彰午9 小时前
政务低代码平台实战⑤:双输出模式——存DB与导出JSP的完整链路
数据库·低代码·政务
梦梦代码精21 小时前
连锁品牌数字化:从门店扩张到用户资产运营的技术底座
大数据·人工智能·低代码·docker·开源·代码规范
SL-staff1 天前
JVS数字底座实践:如何复用企业文档能力快速构建知识类应用
低代码·微服务·springcloud·知识管理·权限控制·jvs·elasticsea
NocoBase2 天前
如何用 AI 和 NocoBase 搭建一套可投入生产的 CRM
低代码·ai·开源·无代码·无代码开发平台
许彰午2 天前
政务低代码平台实战(总纲)——从元数据引擎到可视化设计器的五个关键决策
低代码·rxjava·政务
只会cv的小前端4 天前
七巧低代码表单JS脚本教学
开发语言·javascript·低代码
踩着两条虫5 天前
VTJ.PRO AI Agent 技术白皮书
前端·vue.js·低代码
只会cv的小前端6 天前
七巧低代码服务端脚本使用方法
android·低代码·rxjava
iori97king7 天前
织信开发日志 03:表单引擎从 0 到 1 的设计过程
低代码