Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you need to do this dynamically in KO, then here is an example of a binding that wraps the normal <code>foreach</code> binding and creates a computed on the fly that returns a structure with rows/columns based on a "count" observable.</p> <pre><code>ko.bindingHandlers.foreachGroups = { init: function(element, valueAccessor) { var groupedItems, options = valueAccessor(); //create our own computed that transforms the flat array into rows/columns groupedItems = ko.computed({ read: function() { var index, length, group, result = [], count = +ko.utils.unwrapObservable(options.count) || 1, items = ko.utils.unwrapObservable(options.data); //create an array of arrays (rows/columns) for (index = 0, length = items.length; index &lt; length; index++) { if (index % count === 0) { group = []; result.push(group); } group.push(items[index]); } return result; }, disposeWhenNodeIsRemoved: element }); //use the normal foreach binding with our new computed ko.applyBindingsToNode(element, { foreach: groupedItems }); //make sure that the children of this element are not bound return { controlsDescendantBindings: true }; } }; </code></pre> <p>You would use it like:</p> <pre><code>&lt;div data-bind="foreachGroups: { data: items, count: count }"&gt; &lt;ul data-bind="foreach: $data"&gt; &lt;li data-bind="text: $data"&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; </code></pre> <p>Here is a sample: <a href="http://jsfiddle.net/rniemeyer/F48XU/" rel="nofollow">http://jsfiddle.net/rniemeyer/F48XU/</a></p> <p>For your specific case though, I would probably:</p> <ul> <li>remove the <code>count</code> option and just pass in the items</li> <li>create your own <code>count</code> observable in the <code>init</code> function.</li> <li>add a <code>resize</code> event handler that runs your logic and updates the <code>count</code> observable appropriately.</li> </ul> <p>It might look like (fill in your specific resize logic):</p> <pre><code>ko.bindingHandlers.foreachGroups = { init: function(element, valueAccessor) { var groupedItems, data = valueAccessor(), count = ko.observable(1); ko.utils.registerEventHandler(window, "resize", function() { //run your calculation logic here and update the "count" observable with a new value }); //create our own computed that transforms the flat array into rows/columns groupedItems = ko.computed({ read: function() { var index, length, group, result = [], itemsPerRow = +ko.utils.unwrapObservable(count) || 1, items = ko.utils.unwrapObservable(data); //create an array of arrays (rows/columns) for (index = 0, length = items.length; index &lt; length; index++) { if (index % itemsPerRow === 0) { group = []; result.push(group); } group.push(items[index]); } return result; }, disposeWhenNodeIsRemoved: element }); //use the normal foreach binding with our new computed ko.applyBindingsToNode(element, { foreach: groupedItems }); //make sure that the children of this element are not bound return { controlsDescendantBindings: true }; } }; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload