2012-06-15 6 views
28

Jak używać AngularJS ng-repeat do wyświetlania następującego kodu HTML (Twitter Bootstrap Rusztowanie)? Zasadniczo, co trzeci rekord muszę zamknąć </div>, wydrukować <hr>, następnie otworzyć inny <div class="span4">Jak korzystać z AngularJS ng-repeat z rusztowaniem Twitter Bootstrap?

<div class="row"> 
     <div class="span4"> 
     <h3> 
      Project A 
     </h3> 
     </div> 
     <div class="span4"> 
     <h3> 
      Project B 
     </h3> 
     </div> 
     <div class="span4"> 
     <h3> 
      Project C 
     </h3> 
     </div> 
    </div> 

    <hr> 

    <div class="row"> 
     <div class="span4"> 
     <h3> 
      Project D 
     </h3> 
     </div> 
     <div class="span4"> 
     <h3> 
      Lab Title 
     </h3> 
     </div> 
     <div class="span4"> 
     <h3> 
      Project E 
     </h3> 
     </div> 
    </div> 

Utworzyłem skrzypce dla dema kodowych.
http://jsfiddle.net/ADukg/261/

Odpowiedz

15

bardziej eleganckim sposobem jest skorzystanie z modelu widoku, aby zapewnić pakietowego kolekcję i pozwól widok poradzić jak

<div ng-controller="Controller"> 
    Projects <input ng-model="projects"></input> 
    <hr/> 
    <div ng-repeat="row in rows"> 
     <div ng-repeat="project in row"> 
      Projects {{project}} 
     </div> 
     <hr/> 
    </div> 
</div>​ 

i coffeescript jest dość prosta

# Break up an array into even sized chunks. 
chunk = (a,s)-> 
    if a.length == 0 
     [] 
    else    
     (a[i..i+s-1] for i in [0..a.length - 1 ] by s) 

@Controller = ($scope)-> 
    $scope.projects = "ABCDEF" 

    $scope.$watch "projects", ->  
     $scope.rows = chunk $scope.projects.split(""), 3 

angular.bootstrap(document, []); 

http://jsfiddle.net/ADukg/370/

38

Oto sposób:

<div ng-controller="MyCtrl"> 
    <div ng-repeat="project in projects"> 
    <span ng-if="$index % 3 == 0"> 
     <hr /> 
     <div class="row"> 
     <h3 class="span4" ng-if="projects[$index+0]">{{projects[$index+0]}}</h3> 
     <h3 class="span4" ng-if="projects[$index+1]">{{projects[$index+1]}}</h3> 
     <h3 class="span4" ng-if="projects[$index+2]">{{projects[$index+2]}}</h3> 
     </div> 
    </span> 
    </div> 
</div> 

ten sposób będzie również działać, jeśli masz na przykład 7 elementów danych: na 3 ostatnich danych, pokaże tylko pozycję 7 i nie starają się pokazać nonexistant element 8 i 9.

http://jsfiddle.net/4LhN9/68/

EDIT: zaktualizowana i ng jeśli & kątowej 1. 2,12

+0

Jest to całkiem sprytne rozwiązanie.Ale jak poradziłbyś sobie z przypadkiem, w którym długość zbioru danych nie jest podzielna przez 3? Na przykład mówisz, że wyświetlasz obrazy ... $ index + 0 w ostatnim wierszu wskazuje na URL img, ale +1 i +2 są puste. –

+0

Wyliczyłem to. Po prostu wykonaj ng-show = "! (($ Index + x)> (art.length-1))" na img, gdzie x wynosi odpowiednio 0, 1, 2. Angular jest taki sprytny. –

+0

To jest genialne. @andy dodaj pomysł na rob-ng'a, tutaj i na skrzypce! –

16

Przeprowadzka z the more easy answer. Nie podoba mi się oryginalne rozwiązanie z powodu pustych elementów domena, które produkuje. To jest dla 3 divs na wiersz.

<div ng-controller="ModulesCtrl"> 
    <div class="row" ng-repeat="i in fields.range()"> 
     <div class="span4" ng-repeat="field in fields.slice(i,i+3)"> 
      <h2>{{field}}</h2> 
     </div> 
    </div> 
</div> 

funkcja polamictrl ($ zakres):

$scope.fields.range = function() { 
    var range = []; 
    for(var i = 0; i < $scope.fields.length; i = i + 3) 
     range.push(i); 
    return range; 
} 

Jeśli znasz fields.length można zamiast fields.range() użyj [0,3,6,9] itp

+0

To zadziałało dla mnie! –

2

Aby zachować logikę widok z kontrolera i mieć więcej wielokrotnego użytku rozwiązanie, można utworzyć własny filtr, który dzieli tablicę na grupy rzędu:

angular.module('app').filter('group', function() { 
    /** 
    * splits an array into groups of the given size 
    * e.g. ([1, 2, 3, 4, 5], 2) -> [[1, 2], [3, 4], [5]] 
    */ 
    return function(array, groupSize) { 
     return _.groupBy(array, function(val, index) { 
      return Math.floor(index/groupSize); 
     }); 
    }; 
}); 

I w widoku:

<div class="row" ng-repeat="group in projects | group:3"> 
    <div class="span4" ng-repeat="project in group"> 
     {{project}} 
    </div> 
</div> 

Aby dołączyć HR można użyć NG-repeat punkty początkowe i końcowe:

<div class="row" ng-repeat-start="group in projects | group:3"> 
    <div class="span4" ng-repeat="project in group"> 
     {{project}} 
    </div> 
</div> 
<hr ng-repeat-end /> 
+0

Podoba mi się to w teorii. W praktyce jednak generuje wyjątek '10 $ digest() iteracji '. [Zobacz to skrzypce.] (Http://jsfiddle.net/eVWw5/5/) – roufamatic

+0

Dzięki roufamatic. Przyjrzałem się temu i okazało się, że polecenie ng-repeat używa $ watchCollection do sprawdzania zmian. Ponieważ $ watchCollection robi płytkie porównanie zawartości tablicy, a mój filtr 'group' zwraca nowy zestaw tablic za każdym razem, gdy jest wywoływany, kątowe sądzi, że tablica ciągle się zmienia. Praca polega na zainicjowaniu zgrupowanej tablicy przed ng-repeat zamiast użycia filtra, przy użyciu ng-init lub w kontrolerze. Ale potem traci elegancję. – WearyMonkey

2

ng-repeat-start and ng-repeat-end end points wydaje dogodnym sposobem osiągnięcia tego celu:

Która prowadzi do prostego kodu:

<div ng-controller="MyCtrl"> 
    <div ng-repeat-start="project in projects"> 
     <span> 
      <div class="row"> 
       <h3 class="span4">{{project}}</h3> 
      </div 
     </span> 
    </div> 
    <hr ng-repeat-end ng-if="($index + 1) % 3 == 0" /> 
</div> 

Zobacz tę jsfiddle