用ng-repeat和嵌套循环添加行
我正在寻找一种将行添加到表的方法。 我的数据结构如下所示:
rows = [ { name : 'row1', subrows : [{ name : 'row1.1' }, { name : 'row1.2' }] }, { name : 'row2' } ];
我想创build一个如下所示的表格:
table row1 row1.1 row1.2 row2
这是可能的angularjs ng-repeat? 如果没有,那么做一个“angular度”的方法是什么?
编辑:展平数组将是一个不好的解决scheme,因为如果我可以迭代子元素,我可以在单元格内使用不同的HTML标签,其他CSS类等
你不能用ng-repeat做这个。 不过,你可以用指令来做。
<my-table rows='rows'></my-table>
小提琴 。
myApp.directive('myTable', function () { return { restrict: 'E', link: function (scope, element, attrs) { var html = '<table>'; angular.forEach(scope[attrs.rows], function (row, index) { html += '<tr><td>' + row.name + '</td></tr>'; if ('subrows' in row) { angular.forEach(row.subrows, function (subrow, index) { html += '<tr><td>' + subrow.name + '</td></tr>'; }); } }); html += '</table>'; element.replaceWith(html) } } });
一年多之后,却发现了一个解决方法,至less在两个层面(父亲 – >儿子)。
只要重复tbody
的:
<table> <tbody ng-repeat="row in rows"> <tr> <th>{{row.name}}</th> </tr> <tr ng-repeat="sub in row.subrows"> <td>{{sub.name}}</td> </tr> </tbody> </table>
据我所知,所有的浏览器都支持表格中的多个tbody
元素。
三年多以后,我一直面临同样的问题,在写下指令之前,我试了一下,对我来说效果很好:
<table> <tbody> <tr ng-repeat-start="row in rows"> <td> {{ row.name }} </td> </tr> <tr ng-repeat-end ng-repeat="subrow in row.subrows"> <td> {{ subrow.name }} </td> </tr> </tbody> </table>
我有点惊讶,有这么多人主张自定义指令,并创build由$ watch更新的代理variables。
像这样的问题是AngularJSfilter的原因!
从文档:
A filter formats the value of an expression for display to the user.
我们不想操纵数据,只是格式化,以不同的方式显示。 所以让我们来创build一个filter,它接受我们的行数组,将其弄平,然后返回平展的行。
.filter('flattenRows', function(){ return function(rows) { var flatten = []; angular.forEach(rows, function(row){ subrows = row.subrows; flatten.push(row); if(subrows){ angular.forEach(subrows, function(subrow){ flatten.push( angular.extend(subrow, {subrow: true}) ); }); } }); return flatten; } })
现在我们需要的是将filter添加到ngRepeat中:
<table class="table table-striped table-hover table-bordered"> <thead> <tr> <th>Rows with filter</th> </tr> </thead> <tbody> <tr ng-repeat="row in rows | flattenRows"> <td>{{row.name}}</td> </tr> </tbody> </table>
如果需要,您现在可以自由组合您的表格和其他filter,就像search一样。
虽然多tbody的方法是方便和有效的,它会弄乱任何CSS依赖于子行的顺序或索引,如“条纹”的表,还假定你没有在你的tbody风格方式,你不想重复。
这是一个庞然大物: http : //embed.plnkr.co/otjeQv7z0rifPusneJ0F/preview
编辑:我添加了一个子值,并在表中使用它来显示哪些行是亚行,因为你表示担心能够做到这一点。
是的,这是可能的:
控制器:
app.controller('AppController', [ '$scope', function($scope) { $scope.rows = [ { name : 'row1', subrows : [{ name : 'row1.1' }, { name : 'row1.2' }] }, { name : 'row2' } ]; } ] );
HTML:
<table> <tr ng-repeat="row in rows"> <td> {{row.name}} <table ng-show="row.subrows"> <tr ng-repeat="subrow in row.subrows"> <td>{{subrow.name}}</td> </tr> </table> </td> </tr> </table>
Plunker
如果你不想要子表,平整行(同时注释的亚行,以便能够区分):
控制器:
function($scope) { $scope.rows = [ { name : 'row1', subrows : [{ name : 'row1.1' }, { name : 'row1.2' }] }, { name : 'row2' } ]; $scope.flatten = []; var subrows; $scope.$watch('rows', function(rows){ var flatten = []; angular.forEach(rows, function(row){ subrows = row.subrows; delete row.subrows; flatten.push(row); if(subrows){ angular.forEach(subrows, function(subrow){ flatten.push( angular.extend(subrow, {subrow: true}) ); }); } }); $scope.flatten = flatten; }); }
HTML:
<table> <tr ng-repeat="row in flatten"> <td> {{row.name}} </td> </tr> </table>
Plunker
这是一个例子。 这段代码打印peopeByCity
数组中所有人的所有名字。
TS:
export class AppComponent { peopleByCity = [ { city: 'Miami', people: [ { name: 'John', age: 12 }, { name: 'Angel', age: 22 } ] }, { city: 'Sao Paulo', people: [ { name: 'Anderson', age: 35 }, { name: 'Felipe', age: 36 } ] } ] }
HTML:
<div *ngFor="let personsByCity of peopleByCity"> <div *ngFor="let person of personsByCity.people"> {{ person.name }} </div> </div>