43

我正在寻找一种向表中添加行的方法。我的数据结构如下所示:

  rows = [
    { name : 'row1', subrows : [{ name : 'row1.1' }, { name : 'row1.2' }] },
    { name : 'row2' }
  ];

我想创建一个看起来像这样的表:

  table
     row1
     row1.1
     row1.2
     row2

Angular js ng-repeat有可能吗?如果不是,那么这样做的“角度”方式是什么?

编辑:展平数组将是一个糟糕的解决方案,因为如果我可以迭代子元素,我可以在单元格、其他 css 类等中使用不同的 html 标签。

4

6 回答 6

75

一年多后,但找到了一种解决方法,至少针对两个级别(父亲-> 儿子)。
重复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表格内的多个元素。

于 2013-07-08T18:33:19.310 回答
28

3 年多后,我一直面临同样的问题,在写下指令之前,我尝试了这个,它对我来说效果很好:

<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>
于 2016-04-29T15:16:38.467 回答
23

您将无法使用 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)
        }
    }
});
于 2013-03-12T15:10:46.020 回答
15

我有点惊讶,这么多人提倡自定义指令并创建由 $watch 更新的代理变量。

像这样的问题是 AngularJS 过滤器被制造出来的原因!

从文档:

A filter formats the value of an expression for display to the user.

我们不打算操纵数据,只是将其格式化以便以不同的方式显示。因此,让我们创建一个过滤器,接收我们的 rows 数组,将其展平,然后返回展平后的行。

.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;
}
})

现在我们只需要将过滤器添加到 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>

如果需要,您现在可以自由地将您的表格与其他过滤器组合起来,例如搜索。

虽然多 tbody 方法很方便且有效,但它会弄乱任何依赖子行的顺序或索引的 css,例如“条纹”表,并且还会假设您没有在 tbody 中设置样式不想重复的方式。

这是一个小插曲:http: //embed.plnkr.co/otjeQv7z0rifPusneJ0F/preview

编辑:我添加了一个子行值并在表中使用它来显示哪些行是子行,因为您表示担心能够做到这一点。

于 2014-07-17T16:13:56.440 回答
6

是的,有可能:

控制器:

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>

普朗克

如果您不想要子表,请展平行(同时注释子行,以便能够区分):

控制器:

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>

普朗克

于 2013-03-12T13:49:12.193 回答
0

这是一个例子。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>
于 2017-04-14T18:43:59.330 回答