2011-06-22 3 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);; 
    } 
} 

と同じように使用する:

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

:このバインディングの3つのバリエーションとここ

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

サンプル

+0

ストライプが適用される前にテンプレートレンダリングが確実に行われるようにするにはどうすればいいですか?それとも問題なのでしょうか? – neebz

+1

テンプレートバインディングの後に 'stripe'バインディングを置くだけでよいでしょう。バインディングは左から右に実行されますが、スティーブはそれが必ずしも保証しようとするものではないと言いました。それ以外の場合は、テンプレートバインディングをラップし、順序を絶対に保証する 'templateWithStripe'と呼ばれるバージョンがあります。これは、おそらく最も冗長な構文を提供します。 –

+0

これを見ましたが、より簡単なアプローチが望まれていました。私はこれと一緒に行くだろうと思う。 –

0

あなたはdiv要素のクラスを設定するために、テンプレート内{{if}}{{else}}条件文を使用することができます。

また、現在のアイテムのインデックスを返す関数を含むようにビューモデルを拡張する必要があります。これは、それが奇数か偶数かを示します。 (Something like this

+0

これは静的リストでは機能しますが、項目を削除して追加すると、行に偶数行または奇数行が2つある可能性があります。 –

+0

配列から何かを追加/削除するときにknockoutjsがテンプレート全体を再レンダリングすると思います – neebz

3

これを行う簡単な方法の1つは、各要素にインデックスを追加する計算されたオブザーバブルを追加することです。私の場合は

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はBindingコンテキストで文書化されています。[リンク](http://knockoutjs.com/documentation/binding-context.html) - ありがとう@wesc – ZiglioUK

+3

これは常にあります私の好みの方法であり、受け入れられた答えと比べて、それが提供していないものは見ません。 –

+1

ありがとうございました、私は受け入れられた回答が私の答えに先立っていると思いますので、元のポスターがそれを見直さなければ、それはそのままです。他の誰かがそれを変更できるかどうかわからない – ZiglioUK

0

は完全な例である:FO

<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

感謝r役立つ記事。私はCSSがストライピングの良い仕事をすることができることを言及したいが、埋め込まれた 'if'は行がレンダリングされた後に機能するように思える。したがって、$ indexまたはcssの奇数/偶数機能を使用しても、望ましい結果が得られません。テンプレートを使用せずに、行の周りに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> 
関連する問題