2011-06-22 37 views
24

用KnockoutJS分條列表的最佳方式是什麼?下面div中的類應該是偶數或奇數,取決於它在列表中的位置,並在添加或刪除項目時進行更新。將條紋樣式添加到項目列表中

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

回答

21

有這個就KO論壇上,而回到這裏的話題:https://groups.google.com/d/topic/knockoutjs/cJ2_2QaIJdA/discussion

,我必須是一個自定義綁定解決方案。最近也有一對夫婦的變化,但它基本上看起來像:

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);; 
    } 
} 

和使用,如:這裏

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

樣品與此結合的3個變化:

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

+0

如何確保在應用條紋之前完成模板渲染?或者甚至是一個問題? – neebz

+1

只需要在模板綁定後加上'stripe'綁定就可以了。綁定確實從左到右運行,但史蒂夫已經說過,這不是他想要保證的東西。否則,在小提琴中有一個名爲'templateWithStripe'的版本,它封裝了模板綁定並絕對保證了順序。它可能提供了最簡單的語法。 –

+0

我看到了這個,但我希望有一個更簡單的方法。我想我會和這一起去的。 –

0

您可以使用{{if}}{{else}}條件語句在模板中設置類的div。

此外,您還需要擴展視圖模型以包含一個函數,該函數返回當前項目的索引,它會告訴您它是奇數還是偶數。 (Something like this

+0

這可能適用於靜態列表,但如果我刪除並添加項目,那麼我可以在一行中有兩個偶數或奇數行。 –

+0

我認爲在添加/刪除數組中的某些東西時,knockoutjs會重新渲染整個模板 – neebz

3

這樣做的一個簡單方法是添加一個計算的可觀察值,爲每個元素添加一個索引,例如

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

在我的情況​​將創建一個索引字段,並且均在原始對象的其它字段的對象。

現在你可以斑馬條紋輕鬆地添加到您的輸出:

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

我發現用foreach迭代時,返回索引的功能,這樣你就可以在一個相當緊湊的方式應用偶數和奇數類,例如:

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

$ index記錄在綁定上下文中:[鏈接](http://knockoutjs.com/documentation/binding-context.html) - 謝謝@wesc – ZiglioUK

+3

這一直一直是我的首選方法,我沒有看到它與接受的答案相比沒有提供什麼。 –

+1

謝謝,我認爲接受的答案會在我的答案發布之前發佈,因此除非原始發佈者評論它,否則它將保持原樣。不知道是否有人可以改變這一點 – ZiglioUK

0

這裏是一個完整的例子:

<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

感謝FO r有用的帖子。我想提到的是,CSS可以很好地進行條帶化處理,但嵌入的「if」似乎只能在行被渲染後才起作用。因此,使用$ index或css odd/even功能不會產生所需的結果。在不使用模板的情況下,我發現你可以在行的周圍包裝KO邏輯,以便在行被計數之前發生邏輯。

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