2011-06-22 21 views
24

Jaki byłby najlepszy sposób na rozłożenie listy za pomocą KnockoutJS? Klasa w dziale div powinna być parzysta lub nieparzysta w zależności od tego, gdzie jest na liście, i aktualizować ją podczas dodawania lub usuwania elementów.Dodaj stylizację pasków do listy pozycji

<div class="Headlines loader" 
    data-bind="css: { loader: headlines().length == 0 }, 
         template: { name: 'recentHeadlinesTemplate', 
            foreach: beforeHeadlineAddition, 
            beforeRemove: function(elem) { $(elem).slideUp() }, 
            afterAdd: slideDown }"> 
</div> 

<script type="text/html" id="recentHeadlinesTemplate"> 
    <div class="even"> 
     ${Title} 
    </div> 
</script> 

Odpowiedz

21

Było to tematem na forach KO jakiś czas temu tutaj: https://groups.google.com/d/topic/knockoutjs/cJ2_2QaIJdA/discussion

Rozwiązanie, które miałam zwyczaj wiązania. Było kilka odmian, ale to w zasadzie będzie wyglądać następująco:

ko.bindingHandlers.stripe = { 
    update: function(element, valueAccessor, allBindingsAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); //creates the dependency 
     var allBindings = allBindingsAccessor(); 
     var even = allBindings.evenClass; 
     var odd = allBindings.oddClass; 

     //update odd rows 
     $(element).children(":nth-child(odd)").addClass(odd).removeClass(even); 
     //update even rows 
     $(element).children(":nth-child(even)").addClass(even).removeClass(odd);; 
    } 
} 

i będą używane jak:

<ul data-bind="template: { name: 'itemsTmpl', foreach: items }, stripe: items, evenClass: 'light', oddClass: 'dark'"></ul> 

Sample tu w 3 odmianach tego Oprawa:

http://jsfiddle.net/rniemeyer/HJ8zJ/

+0

, w jaki sposób zapewniamy renderowanie szablonu przed zastosowaniem pasków? czy to nawet problem? – neebz

+1

Wystarczy umieścić wiązanie 'stripe' po powiązaniu szablonu i wszystko będzie dobrze. Wiązania biegną od lewej do prawej, ale Steve powiedział, że nie jest to coś, co stara się koniecznie zagwarantować. W przeciwnym razie istnieje wersja w skrzypcach zwana 'templateWithStripe', która owija wiązanie szablonu i absolutnie gwarantuje kolejność.Prawdopodobnie zapewnia najmniej obszerną składnię. –

+0

Widziałem to, ale miałem nadzieję na prostsze podejście. Chyba pójdę z tym. –

0

można użyć instrukcji warunkowych {{if}} i {{else}} wewnątrz szablonu, aby ustawić klasę div.

Należy również rozszerzyć model widoku, aby uwzględnić funkcję, która zwraca indeks bieżącego elementu, który wskazywałby, czy jest on nieparzysty czy parzysty. (Something like this)

+0

Może to działać dla listy statycznej, ale jeśli usuwam i dodaje elementy, mogę mieć dwa rzędy parzyste lub nieparzyste z rzędu. –

+0

Myślę, że knockoutjs ponownie renderuje cały szablon, dodając/usuwając coś z tablicy – neebz

3

Jednym z łatwych sposobów na to jest dodanie obliczalnego observable, które dodaje indeks do każdego elementu, np.

self.logLines = ko.observable(logLinesInput); 

    self.enhancedLogLines = ko.computed(function() { 
     var res = []; 
     $.each(self.logLines(), function(index, ll) { 
      res.push(new LogLine(index, ll)); 
     }); 
     return res; 
    }, self); 

W moim przypadku LogLine() tworzy obiekt z polem wskazującym i innych dziedzinach, które były w oryginalnym obiektem.

Teraz można łatwo dodawać Zebra do wyjścia:

  <tr data-bind="css: { odd: (index % 2 == 1), even: (index % 2 == 0) }"> 
55

Znalazłem funkcję, która zwraca indeks podczas iteracji z foreach, więc można zastosować parzystych i nieparzystych zajęcia w stosunkowo zwarty sposób na przykład:

<tr data-bind="css: { 'even': ($index() % 2 == 0) }"> 
+4

Indeks $ jest udokumentowany w kontekście powiązania: [link] (http://knockoutjs.com/documentation/binding-context.html) - Dzięki @wesc – ZiglioUK

+3

To zawsze miało miejsce była moją preferowaną metodą i nie widzę tego, czego nie oferuje w porównaniu z zaakceptowaną odpowiedzią. –

+1

Dziękuję, myślę, że zaakceptowana odpowiedź poprzedza moją odpowiedź, więc jeśli oryginalny plakat go nie zrecenzuje, pozostanie taki, jaki jest. Nie jestem pewien, czy ktokolwiek może to zmienić – ZiglioUK

0

tutaj jest pełna przykładów:

<ul class="pickupPointHours" data-bind="foreach: Items"> 
<li data-bind="css: { lineEven: ($index()%2 === 0), lineOdd: ($index()%2 === 1)}"> 
    <span class="pickupPointDay" data-bind="text: TextProperty"></span> 
</li> 
</ul> 
2

Dzięki fo r pomocne posty. Chciałem wspomnieć, że css może wykonać dobrą robotę stripowania, ale osadzone "if" wydaje się działać dopiero po renderowaniu wiersza. Dlatego użycie indeksu $ lub funkcji css nieparzystych/parzystych nie przynosi pożądanych rezultatów. Bez użycia szablonu odkryłem, że można owijać logikę KO wokół rzędu, aby logika wystąpiła przed zliczeniem wiersza.

<tbody data-bind="foreach: viewModel.configuration().items()""> 
    <!-- ko if: $data.part() != '' --> 
    <tr> 
      <td data-bind="text: $index"></td><td data-bind="text: $data.part()"></td> 
    </tr> 
    <!-- /ko --> 
</tbody> 
Powiązane problemy