求助:如何使用UI Grid实现带子网格的可展开行?
实现UI Grid带子网格的自定义可展开行
我太懂你这种碰壁的感觉了——UI Grid自带的展开行和树形视图要么不符合需求,要么用起来处处受限。你要的是主行展开后展示列数、结构和主表格完全不同的子网格对吧?我之前做项目时也踩过这个坑,给你分享一套亲测可行的实现方案:
核心思路
放弃树形视图的同结构展示逻辑,用UI Grid的expandableRowTemplate完全自定义展开区域的内容,在里面嵌入一个独立的子UI Grid,这样子网格的列数、结构就能完全自主控制了。
具体实现步骤
1. 配置主Grid的展开行模板
先创建一个自定义的展开行模板(比如命名为expandable-row-tpl.html),内容就是子Grid的容器:
<div ui-grid="row.entity.subGridOpts" style="height: 200px; margin: 10px;"></div>
然后在主Grid的配置里开启展开行功能并关联这个模板:
$scope.mainGridOpts = { // 关联自定义展开模板 expandableRowTemplate: 'expandable-row-tpl.html', // 设置展开区域的高度,匹配子Grid的实际高度 expandableRowHeight: 220, // 显示行首的展开/折叠按钮 enableExpandableRowHeader: true, // 主Grid的列定义,按你的需求来 columnDefs: [ { name: '主列1' }, { name: '主列2' }, { name: '主列3' } ], // 处理主数据,给每一行绑定子Grid的配置 data: yourMainDataSource.map(item => { // 初始化子Grid配置,列数、列名完全自定义 item.subGridOpts = { // 可以隐藏子Grid的表头,按需设置 showHeader: false, columnDefs: [ { name: '子项ID' }, { name: '子项详情' }, { name: '子项状态' } ], // 子Grid的数据源,和主行数据关联 data: item.subItems }; return item; }) };
2. 处理异步加载的子数据
如果子网格的数据需要从后端异步获取,别在初始化时硬编码,而是利用主Grid的展开事件触发请求:
$scope.mainGridOpts.onRegisterApi = function(gridApi) { $scope.gridApi = gridApi; // 监听行展开事件 gridApi.expandable.on.rowExpanded($scope, function(row) { // 避免重复请求 if (!row.entity.subDataLoaded) { // 模拟异步请求,替换成你的实际接口调用 yourApiService.getSubItems(row.entity.id) .then(subData => { row.entity.subGridOpts.data = subData; row.entity.subDataLoaded = true; }); } }); };
3. 避坑指南
- 子Grid必须设置明确的
height样式,否则会出现渲染异常 - 不要同时开启树形视图和展开行功能,两者的底层机制冲突,会导致奇怪的bug
- 如果主Grid数据是动态更新的,要确保每一行的
subGridOpts都被正确初始化,避免展开时出现空内容
要是你还有没说清楚的具体问题——比如样式错乱、交互异常啥的,可以把场景细节补充一下,我再帮你调整方案。
内容的提问来源于stack exchange,提问作者roxid
相关产品推荐
相关产品推荐

