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-start
和ng-repeat-end
。
这里有一个添加Bootstrap分页的例子:
<ul class="pagination"> <li> <a href="#">«</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="#">»</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-start
和ng-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-start
和ng-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="#">«</a> </li> <li ng-repeat-start="page in [1,2,3,4,5]" ng-repeat-end><a href="#"></a></li> <li> <a href="#">»</a> </li> </ul>
这有三个好处:
- less写html标签
- 无用的,空标签不是由Angular生成的
- 当要重复的数组是空的时候,带有
ng-repeat
的标签将不会被生成,给你相同的优势Knockout的无容器绑定在这方面给你
但是还有一个更干净的方法
在进一步回顾github上有关Angular的这个问题的意见后, https://github.com/angular/angular.js/issues/1891 ,
您不需要使用ng-repeat-start
和ng-repeat-end
来获得相同的优势。 相反,再次分出jmagnusson的例子,我们可以去:
<ul class="pagination"> <li> <a href="#">«</a> </li> <li ng-repeat="page in [1,2,3,4,5,6]"><a href="#">{{page}}</a></li> <li> <a href="#">»</a> </li> </ul>
那么什么时候使用ng-repeat-start
和ng-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>