問題描述

我目前正在使用這段代碼來呈現列表:

<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-startng-repeat-end 添加子元素。

以下是添加 Bootstrap pagination 的一個例子:

<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>

一個完整的工作實例可以找到 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-startng-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-startng-repeat-end 更清潔的方法

在調查 hitautodestruct 的斷言之後,將 ng-repeat-end 添加到單獨的標籤正是我不想在大多數情況下做的,因為它產生完全無用的元素:在這種情況下,<li> 項目中沒有任何內容。 Bootstrap 3 的分頁表列出了列表項,使它看起來像沒有生成任何多餘的項目,但是當您檢查生成的 HTML 時,它們就在那裏。

幸運的是,您不需要做更多的清潔程序和更少的 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. 較少的 html 標籤要寫

  2. 沒有用的空標籤不是由 Angular 生成的

  3. 當要重複的數組為空時,ng-repeat 的標籤將不會生成,給予您同樣的優勢 Knockout 的無容器綁定在這方面給你


但仍然有一個更清潔的方法

在對 Angular,https://github.com/angular/angular.js/issues/1891 這個問題進一步審查 github 的意見後,您不需要使用 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 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇