I have a situation here for the knockout with for each binding with customization
Here is my code:
    
        
      
      
      
        
        
                    - 
            
            
            
                        
 You could create a computed which would pair items, something like the following: self.rows = ko.computed(function(){
    var allItems = self.resultData();
    var rows = [];
    for(var i = 0, len = allItems.length; i < len; i = i+2){
        rows.push({
            leftItem: allItems[i],
            rightItem: i + 1 < len ? allItems[i + 1] : null
        });
    }
    return rows;
});
 You would then bind to the rowsproperty instead of binding directly to theresultDataproperty.
 EDIT: @GOK asked, in a comment, for a version which would allow customizable number of items in a single row. You could achieve this easily by doing something like the following: self.itemsOnEachRow = ko.observable(2);
self.rows = ko.computed(function(){
    var allItems = self.resultData();
    var itemsPerRow = self.itemsOnEachRow();
    var rows = [];
    for(var i = 0, len = allItems.length; i < len; i = i + itemsPerRow){
        var row = {};
        for(var itemIndex = 0; itemIndex < itemsPerRow; itemIndex++){
            var item = null;
            if (i + itemIndex < len){
                item = allItems[i + itemIndex];
            }
            row['item' + itemIndex] = item;
        }
        rows.push(row);
    }
    return rows;
});
 Each row would then have properties named item1,item2, etc, to the number of items set by theitemsOnEachRowobservable (some of these properties might hold a null reference, if the total item count isn't evenly divisible by the items per row count).
 I have written a sample on this, which you can find on http://jsfiddle.net/af7P2/, but I do not suggest binding the table in the way it is done in that sample. I'm not sure how it would set up subscriptions, but it might subscribe a multitude of times to the columnscomputed, one time for each row. It's just there to show a sample of therowscomputed, not for anything else.
 If you want each row to be an array in itself, you could do it with the following code: self.itemsOnEachRow = ko.observable(2);
self.rows = ko.computed(function(){
    var allItems = self.resultData();
    var itemsPerRow = self.itemsOnEachRow();
    var rows = [];
    for(var i = 0, len = allItems.length; i < len; i = i + itemsPerRow){
        var row = [];
        for(var itemIndex = 0; itemIndex < itemsPerRow; itemIndex++){
            var item = null;
            if (i + itemIndex < len){
                item = allItems[i + itemIndex];
            }
            row.push(item);
        }
        rows.push(row);
    }
    return rows;
});
 The bindings for this version (which you can find at http://jsfiddle.net/af7P2/1/) is a bit better, since it doesn't use the columnscomputed one time for each row.
 In general, this solution might not perform very well, depending on your situation. Any addition/removal of items to the resultDataarray, or a change to theitemsOnEachRowvalue, would rebind the whole table. Might not be a problem for you, just something to be aware of.
 讨论(0)