Angular中迭代可折叠Bootstrap数据表的实现难题
解决AngularJS中Bootstrap折叠表格父子行的动态迭代问题
我之前刚好碰到过一模一样的场景!当用AngularJS配合Bootstrap做折叠表格时,普通的ng-repeat只能作用于单个DOM元素,确实搞不定父行+多子行的组合。不过AngularJS其实有专门的方案,再结合动态绑定折叠目标,就能完美实现需求。
核心解决方案:用ng-repeat+动态折叠目标
首先要解决的是折叠目标不唯一的问题——你原来用固定类名.order11,会导致所有父行触发同一个折叠块,所以要给每个父行绑定唯一的目标类名。然后利用嵌套ng-repeat来渲染子行,具体代码如下:
<!-- 父行:遍历每个水果,绑定唯一折叠目标 --> <tr data-toggle="collapse" data-target=".order-{{$index}}" ng-repeat="fruit in result.fruit"> <td>{{fruit.fruitName}}</td> <td>All</td> <!-- 筛选当前水果的"All"季节数据 --> <td>{{ (fruit.season | filter: {seasonName: 'All'})[0].yearValues[0].value }}</td> <td>{{ (fruit.season | filter: {seasonName: 'All'})[0].yearValues[1].value }}</td> <td>{{ (fruit.season | filter: {seasonName: 'All'})[0].yearValues[0].value + (fruit.season | filter: {seasonName: 'All'})[0].yearValues[1].value }}</td> </tr> <!-- 子行:遍历当前水果下非"All"的季节,绑定对应父行的折叠类 --> <tr class="collapse order-{{$parent.$index}}" ng-repeat="season in fruit.season | filter: {seasonName: '!All'}"> <td></td> <td>{{season.seasonName}}</td> <td>{{season.yearValues[0].value}}</td> <td>{{season.yearValues[1].value}}</td> <td>{{season.yearValues[0].value + season.yearValues[1].value}}</td> </tr>
关键细节说明
- 动态折叠目标:用
.order-{{$index}}代替固定类名,每个父行的$index是唯一的,确保点击父行只会展开自己对应的子行 - AngularJS过滤器:
filter: {seasonName: 'All'}快速筛选出总览季节的数据,filter: {seasonName: '!All'}筛选出具体月份的季节 - 实时计算总和:最后一列的年度总和直接通过AngularJS表达式计算,无需额外处理
优化建议:预处理数据让模板更简洁
如果觉得模板里的过滤器重复太多,可以在控制器里提前处理数据,把每个水果的总览和明细季节分开,这样模板会更清晰,性能也更好:
// 在控制器中预处理数据 $scope.result.fruit.forEach(function(fruit) { // 提取总览季节数据 fruit.totalSeason = fruit.season.find(season => season.seasonName === 'All'); // 提取明细季节(排除"All") fruit.detailSeasons = fruit.season.filter(season => season.seasonName !== 'All'); });
修改后的模板:
<tr data-toggle="collapse" data-target=".order-{{$index}}" ng-repeat="fruit in result.fruit"> <td>{{fruit.fruitName}}</td> <td>All</td> <td>{{fruit.totalSeason.yearValues[0].value}}</td> <td>{{fruit.totalSeason.yearValues[1].value}}</td> <td>{{fruit.totalSeason.yearValues[0].value + fruit.totalSeason.yearValues[1].value}}</td> </tr> <tr class="collapse order-{{$parent.$index}}" ng-repeat="season in fruit.detailSeasons"> <td></td> <td>{{season.seasonName}}</td> <td>{{season.yearValues[0].value}}</td> <td>{{season.yearValues[1].value}}</td> <td>{{season.yearValues[0].value + season.yearValues[1].value}}</td> </tr>
这样模板逻辑更直观,也避免了重复调用过滤器,在数据量较大时优势更明显。
内容的提问来源于stack exchange,提问作者forgottofly
相关产品推荐
相关产品推荐

