Given the principle that things related to display, or preparations therefor, belong in the component, I would prefer the component. You could do it like so:
partitions: computedPartition('model', 2)
Then in your template
{{#each partition in partitions}}
<div>
{{#each node in partition}}
{{node.name}}
{{/each}}
</div>
{{/each}}
Now it remains to write computedPartition
, which is an Ember computed property:
function computedPartition(dependentKey, size) {
return Ember.computed(dependentKey + ".@each", function() {
return partition(this.get(dependentKey), size);
});
}
There are different algorithms for partitioning. See this question. Here's a short recursive one:
function partition(array, n) {
array = array.slice();
return function _partition() {
return array.length ? [array.splice(0, n)].concat(_partition()) : [];
}();
}
Going deeper
We can simplify (?) the above by introducing a higher-level computed property called computedArrayInvoke
, which invokes a specified function on the array-valued property with the specified key, along with additional arguments:
function computedArrayInvoke(fn, dependentKey, ...args) {
return Ember.computed(dependentKey + ".@each", function() {
return fn(this.get(dependentKey), ...args);
});
}
Now we can write
partitions: computedArrayInvoke(partition, 'model', 2)