2011-10-06 14 views
13

の最大の動的な列が、リミット、私は同様の質問/ここに答えが見つかりました:How to render a table with some fixed and some dynamic columnsKnockout.jsの行ごとに5

をしかし、それは完全に私の問題を解決していません。私は動的な列の数を行ごとに5に制限する方法と、ビューモデルに5つ以上の項目がある場合は、新しい行を作成し、配列内の5のすべてのグループに対して繰り返す方法を見つけようとしています。例えば

var vm = { 
    item: { name: 'test1' }, 
    item: { name: 'test2' }, 
    item: { name: 'test3' }, 
    item: { name: 'test4' }, 
    item: { name: 'test5' }, 
    item: { name: 'test6' } 
}; 

は、そのモデルを与える、どのように私は、このテーブルを得ることができますか?

<table> 
    <tr> 
     <td>test1</td> 
     <td>test2</td> 
     <td>test3</td> 
     <td>test4</td> 
     <td>test5</td> 
    </tr> 
    <tr> 
     <td>test6</td> 
    <tr> 
</table> 

答えて

24

このような状況を処理するには、ロジックをビューモデルにプッシュして、ビューを単純なままにすることができます。ですから、あなたの "行"を表すためにdependentObservableを使うことが考えられます。次に、あなたのビューは、行をforeachし、行の中のセルをforeachすることができます。

これは、動的に更新できるように、その数の列を観測可能にするサンプルです。 http://jsfiddle.net/rniemeyer/9TN9W/

var viewModel = { 
    items: ko.observableArray(), 
    columnLength: ko.observable(5) 
}; 

//sample data 
for (var i = 0; i < 100; i++) { 
    viewModel.items.push({ name: 'test' + i }); 
} 

//return an array of rows. Each row is an array of items 
viewModel.rows = ko.dependentObservable(function() { 
    var result = [], 
     colLength = parseInt(this.columnLength(), 10), 
     row; 


    //loop through items and push each item to a row array that gets pushed to the final result 
    for (var i = 0, j = this.items().length; i < j; i++) { 
     if (i % colLength === 0) { 
      if (row) { 
       result.push(row);  
      } 
      row = []; 
     } 
     row.push(this.items()[i]); 
    } 

    //push the final row 
    if (row) { 
     result.push(row); 
    } 

    return result; 
}, viewModel); 
+0

ああ、それは完璧で、私はそれらのviewModelの変更で生きることができます。私はおそらく、あなたが実証したのと同じように、この問題に対処するためにJavaScriptを操作しながら、サーバーから出力されたviewModelを同じに保ちます。どうもありがとうございました! :) – ChrisS

+2

ソリューションの例に興味がある人は、ここで私が最終的に終わったのです:http://jsfiddle.net/cmschick/hyHQW/最後に、私はちょうどテーブルを動的に作成します。この例では、並べ替え、バインディング、更新、テキストをラップしない動的な列などがたくさんありますが、それは誰かにとって参考になるかもしれません。 – ChrisS

+0

+1恐ろしい、ちょうど私が探していたもの: –

1

私は解決策を得ることができました最も近いがこれです:

<table> 
    <tbody> 
      <tr data-bind="template: { name: 'rowTmpl', foreach: items}"> 

      </tr> 
    </tbody> 
</table> 
<script id="rowTmpl" type="text/html"> 

     <td data-bind="text: name"></td> 

     <!-- ko if: (vm.items.indexOf($data) + 1) % 5 == 0 --> 
     <td>new row html here</td> 
     <!-- /ko --> 

</script> 


vm = { 

      items: ko.observableArray([ 
       { name: 'test1' }, 
       { name: 'test2' }, 
       { name: 'test3' }, 
       { name: 'test4' }, 
       { name: 'test5' }, 
       { name: 'test6' } 
      ]) 
     } 

     ko.applyBindings(vm); 

。これを出力する:

| test1 | test2 | test3 | test4 | test5 |新しい行はここにHTML |テスト6 |

これは、5番目の項目ごとに新しい要素を挿入します。しかし、<td>new row html here</td></tr><tr>に置き換えると、テンプレートエンジンはエラーをスローします。たぶん、他のSO-erはこれをベースにして、厳密に正しいHTMLを出力しない方法を示すことができます。

とにかく、これが少し助けてくれることを願っています。

+0

ありがとうございました。それは私が得ることができる限りかなりです。私は何とか$ parentバインディングスコープを呼び出して、別のtrをプッシュするためにテンプレートを変更する必要があるかのように思えます...どうしたらいいのでしょうか?こんにちはSteve Sandersonさん、どうやってこれをやることができますか?ありがとう。 – ChrisS

関連する問題