如何在AG-Grid表格中实现指定的多级可展开结构?
AG-Grid 自定义分组展开实现方案
核心配置思路
针对需求,通过自定义分组逻辑+动态展开控制实现,核心利用AG-Grid的isRowExpandable回调、嵌套列配置和自定义分组渲染来精准匹配设计要求。
1. 数据结构预处理
确保数据源为嵌套结构,方便层级展开:
const rowData = [ { email: 'user@example.com', userName: '张三', phone: '138xxxxxxx', channels: [ { channelType: 'APP', channelDetails: [ { channelName: 'iOS端', status: '活跃' }, { channelName: '安卓端', status: '活跃' } ] }, { channelType: 'WEB', channelDetails: [{ channelName: '官网', status: '已停用' }] } ] } ];
2. 列配置(匹配图示顺序)
按mockup顺序定义列,将邮箱设为一级分组,渠道类型设为二级分组:
const columnDefs = [ { field: 'email', rowGroup: true, hide: false, headerName: '邮箱' }, // 主分组字段,直接显示 { field: 'userName', headerName: '用户名' }, { field: 'phone', headerName: '手机号' }, // 渠道信息嵌套列 { headerName: '渠道信息', children: [ { field: 'channelType', rowGroup: true, hide: false, headerName: '渠道类型' }, // 二级分组 { field: 'channelName', headerName: '渠道名称' }, { field: 'status', headerName: '状态' } ] } ];
3. 精准控制展开条件
通过isRowExpandable回调,仅让符合条件的行支持展开:
const gridOptions = { // 其他基础配置 isRowExpandable: (params) => { if (!params.node.group) return false; // 叶子节点不可展开 // 一级分组(邮箱行):渠道数≥2时可展开 if (params.node.field === 'email') { const userData = params.node.allLeafChildren[0].data; return userData.channels.length >= 2; } // 二级分组(渠道类型行):渠道明细数>1时可展开 if (params.node.field === 'channelType') { const channelData = params.node.allLeafChildren[0].data; return channelData.channelDetails.length > 1; } return false; }, autoGroupColumnDef: { cellRendererParams: { suppressCount: true // 隐藏默认分组数量,匹配mockup样式 } } };
4. 自定义分组行渲染(可选)
如果需要完全匹配mockup的分组行样式,可自定义渲染器:
const gridOptions = { // ...其他配置 autoGroupColumnDef: { cellRenderer: 'customGroupRenderer' }, components: { customGroupRenderer: (params) => { const container = document.createElement('div'); // 添加展开/折叠图标(AG-Grid自动绑定点击事件) const icon = document.createElement('span'); icon.className = params.node.expanded ? 'ag-icon ag-icon-collapse' : 'ag-icon ag-icon-expand'; // 添加分组文本 const text = document.createElement('span'); text.textContent = params.node.field === 'email' ? params.node.key : `渠道类型:${params.node.key}`; container.appendChild(icon); container.appendChild(text); return container; } } };
内容的提问来源于stack exchange,提问作者Madalin Puscas
相关产品推荐
相关产品推荐

