問題描述
我目前正在使用這段代碼來呈現列表:
<ul ng-cloak>
<div ng-repeat="n in list">
<li><a href="http://%20n[1]%20">{{ n[0] }}</a></li>
<li class="divider"></i>
</div>
<li>Additional item</li>
</ul>
但是,<div>
元素在某些瀏覽器上導致一些非常小的渲染缺陷。我想知道有沒有辦法做一個沒有 div 容器的 ng-repeat,或者一些替代方法來達到同樣的效果。
最佳解決方案
正如 Andy Joslin 所説,他們正在從事基於評論的 ng-repeats but apparently there were too many browser issues 。幸運的是 AngularJS 1.2 添加了內置支持重複,而不用新的指令 ng-repeat-start
和 ng-repeat-end
添加子元素。
以下是添加 Bootstrap pagination 的一個例子:
<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>
一個完整的工作實例可以找到 here 。
約翰·林德奎斯特也有一個 video tutorial of this over at his excellent egghead.io page 。
次佳解決方案
KnockoutJS 無容器綁定語法
請耐心等待一次:KnockoutJS 提供了一個 ultra-convenient 選項,該選項對 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 不提供這種類型的語法。
角度 ng-repeat-start
和 ng-repeat-end
以 AngularJS 的方式解決 ng-repeat
問題,我遇到的樣本是他 (有幫助的) 答案中發佈的 jmagnusson 類型。
<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>
項目中沒有任何內容。 Bootstrap 3 的分頁表列出了列表項,使它看起來像沒有生成任何多餘的項目,但是當您檢查生成的 HTML 時,它們就在那裏。
幸運的是,您不需要做更多的清潔程序和更少的 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>
這有三個優點:
-
較少的 html 標籤要寫
-
沒有用的空標籤不是由 Angular 生成的
-
當要重複的數組為空時,
ng-repeat
的標籤將不會生成,給予您同樣的優勢 Knockout 的無容器綁定在這方面給你
但仍然有一個更清潔的方法
在對 Angular,https://github.com/angular/angular.js/issues/1891 這個問題進一步審查 github 的意見後,您不需要使用 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 documentation,至
…repeat a series of elements instead of just one parent element…
足夠講話,展示一些例子!
很公平; 這個 jsbin 通過五個例子説明當你做的時候會發生什麼,當你不在同一個標簽上使用 ng-repeat-end
時。
http://jsbin.com/eXaPibI/1/
第三種解決方案
ngRepeat 可能還不夠,但是您可以將其與自定義指令組合。如果你不介意一點點的 jQuery,你可以委託把代碼添加到代碼中的任務。
<li ng-repeat="item in coll" so-add-divide="your exp here"></li>
這樣一個簡單的指令並不需要一個屬性值,但是可能會給你很多可能性,例如有條件地根據索引,長度等添加一個除法器,或者完全不同。
第四種方案
我最近有同樣的問題,因為我不得不重複任意的跨度和圖像的集合 – 在它們周圍有一個元素不是一個選擇 – 但是有一個簡單的解決方案,創建一個”null” 指令:
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 元素渲染時,但再次檢查它不… 仍然解決了我的佈局問題,雖然… curioser 和 curioser …
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。