如何在没有html元素的情况下使用ng-repeat

fad*_*bee 139 angularjs

我需要使用ng-repeat(在AngularJS中)列出数组中的所有元素.

复杂的是,数组的每个元素都将转换为表的一行,两行或三行.

我无法创建有效的html,如果ng-repeat在元素上使用,因为在<tbody>和之间不允许任何类型的重复元素<tr>.

例如,如果我使用ng-repeat <span>,我会得到:

<table>
  <tbody>
    <span>
      <tr>...</tr>
    </span>
    <span>
      <tr>...</tr>
      <tr>...</tr>
      <tr>...</tr>
    </span>
    <span>
      <tr>...</tr>
      <tr>...</tr>
    </span>
  </tbody>
</table>          
Run Code Online (Sandbox Code Playgroud)

这是无效的HTML.

但我需要生成的是:

<table>
  <tbody>
    <tr>...</tr>
    <tr>...</tr>
    <tr>...</tr>
    <tr>...</tr>
    <tr>...</tr>
    <tr>...</tr>
  </tbody>
</table>          
Run Code Online (Sandbox Code Playgroud)

其中第一行由第一个数组元素生成,接下来的三个由第二个数据生成,第五个和第六个由最后一个数组元素生成.

如何在渲染过程中使用ng-repeat以使其绑定的html元素"消失"?

或者还有另一个解决方案吗?


澄清:生成的结构应如下所示.每个数组元素可以生成1-3行的表.理想情况下,答案应该支持每个数组元素0-n行.

<table>
  <tbody>
    <!-- array element 0 -->
    <tr>
      <td>One row item</td>
    </tr>
    <!-- array element 1 -->
    <tr>
      <td>Three row item</td>
    </tr>
    <tr>
      <td>Some product details</td>
    </tr>
    <tr>
      <td>Customer ratings</td>
    </tr>
    <!-- array element 2 -->
    <tr>
      <td>Two row item</td>
    </tr>
    <tr>
      <td>Full description</td>
    </tr>
  </tbody>
</table>          
Run Code Online (Sandbox Code Playgroud)

jma*_*son 73

从AngularJS 1.2开始,有一个叫做的指令ng-repeat-start正是你所要求的.有关如何使用它的说明,请参阅此问题中的答案.


Mar*_*cok 66

更新:如果您使用的是Angular 1.2+,请使用ng-repeat-start.请参阅@jmagnusson的回答.

否则,如何将ng-repeat放在tbody上?(AFAIK,可以在一个表中有多个<tbody>.)

<tbody ng-repeat="row in array">
  <tr ng-repeat="item in row">
     <td>{{item}}</td>
  </tr>
</tbody>
Run Code Online (Sandbox Code Playgroud)

  • 虽然这在技术上可行,但令人非常失望的是,这个常见用例的答案是你必须注入任意(否则是不必要的)标记.我有同样的问题(重复的行组 - 一个标题TR与一个或多个子TR,作为一组重复).与其他模板引擎一样琐碎,看起来最好与Angular一起使用. (62认同)
  • 这个答案已经过时,请改用ng-repeat-start (3认同)
  • @DavidLin,在Angular v1.2中(无论何时出现)你将能够重复多个元素,例如dt和dd:http://www.youtube.com/watch?v = W13qDdJDHp8&t = 17m28s (2认同)

Duk*_*pád 31

如果您使用ng> 1.2,以下是使用ng-repeat-start/end而不生成不必要的标记的示例:

<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <script>
      angular.module('mApp', []);
    </script>
  </head>
  <body ng-app="mApp">
    <table border="1" width="100%">
      <tr ng-if="0" ng-repeat-start="elem in [{k: 'A', v: ['a1','a2']}, {k: 'B', v: ['b1']}, {k: 'C', v: ['c1','c2','c3']}]"></tr>

      <tr>
        <td rowspan="{{elem.v.length}}">{{elem.k}}</td>
        <td>{{elem.v[0]}}</td>
      </tr>
      <tr ng-repeat="v in elem.v" ng-if="!$first">
        <td>{{v}}</td>
      </tr>

      <tr ng-if="0" ng-repeat-end></tr>
    </table>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

重点:对于用于ng-repeat-startng-repeat-end设置的标签ng-if="0",不要在页面中插入.通过这种方式,内部内容将完全按照knockoutjs中的内容处理(使用命令<!--...-->),并且不会有垃圾.


btf*_*ord 18

您可能希望压缩控制器中的数据:

function MyCtrl ($scope) {
  $scope.myData = [[1,2,3], [4,5,6], [7,8,9]];
  $scope.flattened = function () {
    var flat = [];
    $scope.myData.forEach(function (item) {
      flat.concat(item);
    }
    return flat;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在HTML中:

<table>
  <tbody>
    <tr ng-repeat="item in flattened()"><td>{{item}}</td></tr>
  </tbody>
</table>
Run Code Online (Sandbox Code Playgroud)

  • 在更广泛的背景下,这是正确的答案. (5认同)

Αλέ*_*κος 5

以上是正确的,但对于更一般的答案,这是不够的.我需要嵌套ng-repeat,但保持相同的html级别,这意味着在同一个父级中编写元素.tags数组包含也有tags数组的标签.它实际上是一棵树.

[{ name:'name1', tags: [
  { name: 'name1_1', tags: []},
  { name: 'name1_2', tags: []}
  ]},
 { name:'name2', tags: [
  { name: 'name2_1', tags: []},
  { name: 'name2_2', tags: []}
  ]}
]
Run Code Online (Sandbox Code Playgroud)

所以这就是我最终做的.

<div ng-repeat-start="tag1 in tags" ng-if="false"></div>
    {{tag1}},
  <div ng-repeat-start="tag2 in tag1.tags" ng-if="false"></div>
    {{tag2}},
  <div ng-repeat-end ng-if="false"></div>
<div ng-repeat-end ng-if="false"></div>
Run Code Online (Sandbox Code Playgroud)

注意隐藏起始和结束div的ng-if ="false".

它应该打印

NAME1,name1_1,name1_2,NAME2 NAME2_1,name2_2,