簡體   English   中英

AngularJS ng-repeat沒有html元素

[英]AngularJS ng-repeat with no html element

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

<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,或者有一些替​​代方法來實現相同的效果。

正如安迪·喬斯林所說他們正在研究基於注釋的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>

這里可以找到完整的工作示例。

John Lindquist還在他出色的egghead.io頁面上有一個關於此視頻教程

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不提供這種語法。


Angular的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中更容易? 但是hitautodestruct在jmagnusson的回答中的評論開始讓我想知道:在單獨的標簽上使用ng-repeat-start和ng-repeat-end生成什么?


使用ng-repeat-startng-repeat-end更簡潔方法

在hitautodestruct的說法進行調查,將ng-repeat-end上一個單獨的標簽是什么我希望在大多數情況下這樣做,因為它會產生完全usesless元素:在這種情況下, <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的無容器綁定在這方面為您提供

但仍有一種更清潔的方式

在進一步審查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 根據角度文檔 ,到

...重復一系列元素而不只是一個父元素......

足夠的談話,展示一些例子!

很公平; 這個jsbin通過五個例子來說明當你這樣做時以及你在同一個標​​簽上不使用ng-repeat-end時會發生什么。

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

ngRepeat可能還不夠,但您可以將它與自定義指令結合使用。 如果你不介意一點點jQuery,你可以委托將divider項添加到代碼中的任務。

 <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上使用repeat,其中element.url指向該元素的模板:

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

這將重復任意數量的不同模板,周圍沒有容器

注意:嗯,我可以發誓盲目在渲染時刪除了di-null元素,但再次檢查它不會......仍然解決了我的布局問題,但是...好奇者和好奇者......

有一個注釋指令限制,但ngRepeat不支持它(因為它需要一個元素重復)。

我想我看到有角度的團隊說他們會繼續評論重復評論,但我不確定。 您應該在回購中為它打開一個問題。 http://github.com/angular/angular.js

沒有Angular魔術方法可以做到這一點,對於你的情況你可以這樣做,以獲得有效的HTML,如果你使用Bootstrap。 然后你將獲得與添加li.divider相同的效果

創建一個類:

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>

一個真正有效的解決方案

HTML

<remove  ng-repeat-start="itemGroup in Groups" ></remove>
   html stuff in here including inner repeating loops if you want
<remove  ng-repeat-end></remove>

添加angular.js指令

//remove directive
(function(){
    var remove = function(){

        return {    
            restrict: "E",
            replace: true,
            link: function(scope, element, attrs, controller){
                element.replaceWith('<!--removed element-->');
            }
        };

    };
    var module = angular.module("app" );
    module.directive('remove', [remove]);
}());

為了簡要說明,

ng-repeat將自身綁定到<remove>元素並按原樣循環,因為我們使用了ng-repeat-start / ng-repeat-end,它循環一個html塊而不僅僅是一個元素。

然后自定義remove指令將<remove>開始和結束元素放在<!--removed element-->

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM