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,加载完自动关闭

相关推荐
逻辑孤独1 天前
小店进销存实操:扫码收货、卖货、盘货三个环节
低代码
三号路口1 天前
消息推送去重:同一事件只提醒一次的实现
低代码
内存过载1 天前
用表格模拟甘特图:项目排期的土办法
前端·低代码
百数平台1 天前
六大 AI 智能体业务场景:表单、巡检、合同审查落地实践
低代码·ai
wewowilling1 天前
工作流 .... coze平台--AI--Agent--RAG--Function Calling
python·低代码·agent·零代码·工作流·coze
Geek-Chow2 天前
06 · n8n 源码剖析:完整走查——Ada 的订单,从头到尾
低代码
流星。。方2 天前
老官网改版实录:3步保留URL与收录,渐进式适配移动端
低代码
液态不合群2 天前
AI低代码政务落地:破解信息化低效困局的核心逻辑
人工智能·低代码·数字化·政务
RuoyiOffice2 天前
Springboot + Vue3 + FormCreate表单引擎,直接用AI对话进行单据设计,告别拖拽画表单
spring boot·低代码·vue3·sse·formcreate·ruoyi office·ai表单
SL_staff3 天前
JVS混合架构实践:能力引擎+动态模型如何支撑企业级可持续交付
spring boot·低代码·全栈