AngularJS ng-repeat没有html元素

我目前正在使用这段代码来呈现一个列表:

<ul ng-cloak> <div ng-repeat="n in list"> <li><a href="{{ n[1] }}">{{ n[0] }}</a></li> <li class="divider"></i> </div> <li>Additional item</li> </ul> 

但是, <div>元素在某些浏览器上导致一些非常小的渲染缺陷。 我想知道是否有一种方法可以在不使用div容器的情况下执行ng-repeat,或者使用其他方法来实现相同的效果。

正如安迪·乔斯林(Andy Joslin)所说,他们正在进行基于评论的ng-repeats, 但显然浏览器问题太多了 。 幸运的是,AngularJS 1.2增加了内置的重复支持,无需添加新的指令ng-repeat-startng-repeat-end

这里有一个添加Bootstrap分页的例子:

 <ul class="pagination"> <li> <a href="#">&laquo;</a> </li> <li ng-repeat-start="page in [1,2,3,4,5,6]"><a href="#">{{page}}</a></li> <li ng-repeat-end class="divider"></li> <li> <a href="#">&raquo;</a> </li> </ul> 

一个完整的工作示例可以在这里find。

John Lindquist 在他精彩的egghead.io页面上也有一个video教程 。

KnockoutJS无容器绑定语法

请耐心等待:KnockoutJS为foreach绑定提供了一个非常方便的选项,如foreach绑定文档的注释4所述。 http://knockoutjs.com/documentation/foreach-binding.html

如Knockout文档示例所示,您可以在KnockoutJS中编写您的绑定,如下所示:

 <ul> <li class="header">Header item</li> <!-- ko foreach: myItems --> <li>Item <span data-bind="text: $data"></span></li> <!-- /ko --> </ul> 

我认为这是相当不幸的AngularJS不提供这种types的语法。


Angular的ng-repeat-startng-repeat-end

在AngularJS解决ng-repeat问题的方式中,我遇到的样本是jmagnusson在他的(有用的)答案中发布的types。

 <li ng-repeat-start="page in [1,2,3,4,5]"><a href="#">{{page}}</a></li> <li ng-repeat-end></li> 

我看到这个语法的原始思想是:真的吗? 为什么Angular强迫所有这些额外的标记,我不想要做什么,而且在Knockout中更容易? 但是,然后在jmagnusson的答案中,hitautodestruct的评论开始让我怀疑:ng-repeat-start和ng-repeat-end在不同的标签上产生了什么?


使用ng-repeat-startng-repeat-end更简洁的方法

在调查hitautodestruct的断言之后,将ng-repeat-end添加到单独的标记中正是我在大多数情况下不想做的事情,因为它会生成完全无用的元素:在这种情况下, <li>项中没有任何内容。 引导3的分页列表样式的列表项目,以便它看起来像你没有生成任何多余的项目,但是当你检查生成的HTML,他们在那里。

幸运的是 ,你不需要做太多的工作来获得更清晰的解决scheme和更less量的html: 只要将ng-repeat-end声明放在具有ng-repeat-start html标签上

 <ul class="pagination"> <li> <a href="#">&laquo;</a> </li> <li ng-repeat-start="page in [1,2,3,4,5]" ng-repeat-end><a href="#"></a></li> <li> <a href="#">&raquo;</a> </li> </ul> 

这有三个好处:

  1. less写html标签
  2. 无用的,空标签不是由Angular生成的
  3. 当要重复的数组是空的时候,带有ng-repeat的标签将不会被生成,给你相同的优势Knockout的无容器绑定在这方面给你

但是还有一个更干净的方法

在进一步回顾github上有关Angular的这个问题的意见后, https://github.com/angular/angular.js/issues/1891
您不需要使用ng-repeat-startng-repeat-end来获得相同的优势。 相反,再次分出jmagnusson的例子,我们可以去:

 <ul class="pagination"> <li> <a href="#">&laquo;</a> </li> <li ng-repeat="page in [1,2,3,4,5,6]"><a href="#">{{page}}</a></li> <li> <a href="#">&raquo;</a> </li> </ul> 

那么什么时候使用ng-repeat-startng-repeat-end呢? 根据angular度的文件 ,以

重复一系列元素而不是一个父元素

说够了,举几个例子!

很公平; 这个jsbin通过五个例子来说明当你做什么,当你不使用ng-repeat-end在同一个标​​签上时。

http://jsbin.com/eXaPibI/1/

ngRepeat可能不够,但是你可以把它和自定义指令结合起来。 如果你不介意一点点的jQuery,你可以委托添加分隔条目到代码的任务。

  <li ng-repeat="item in coll" so-add-divide="your exp here"></li> 

这样一个简单的指令并不是真的需要一个属性值,但可能会给你很多的可能性,如根据索引,长度等有条件地添加分隔符或完全不同的东西。

我最近有同样的问题,我不得不重复一个任意的跨度和图像集合 – 有一个元素周围是不是一个选项 – 有一个简单的解决scheme,但是,创build一个“空”指令:

 app.directive("diNull", function() { return { restrict: "E", replace: true, template: "" }; }); 

然后,您可以对该元素使用重复,其中element.url指向该元素的模板:

 <di-null ng-repeat="element in elements" ng-include="element.url" ></di-null> 

这将重复任何数量的不同的模板,没有周围的容器

注意:嗯,我可以发誓盲目,当渲染时删除di-null元素,但再次检查它不…仍然解决了我的布局问题,虽然…古怪和好奇…

有一个注释指令限制,但ngRepeat不支持它(因为它需要一个元素重复)。

我想我看到了这个angular色团队说他们会在评论中重复使用,但我不确定。 你应该在回购中为它打开一个问题。 angular/angular.html

没有Angular魔术的方法来做到这一点,你的情况下,你可以做到这一点,以获得有效的HTML,如果你正在使用Bootstrap。 然后你会得到与添加li.divider相同的效果

创build一个类:

 span.divider { display: block; } 

现在将您的代码更改为:

 <ul ng-cloak> <li div ng-repeat="n in list"> <a href="{{ n[1] }}">{{ n[0] }}</a> <span class="divider"></span> </li> <li>Additional item</li> </ul>