I am using a Knockout Custom Binding handler (borrowed from Creating groups with Knockout.js foreach). Within the nested markup, I'd like to reference an observable that is located on the root of the view model. However the binding fails because $root is undefined. The same markup works fine with a standard foreach binding. I don't know why the custom hander prevents using $root.
Here is the source for the binding handler :
ko.bindingHandlers.foreachGrouped = {
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 < 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 };
}
};
Here is the html markup:
Header Text: <input data-bind="value: header" />
Group count: <input data-bind="value: count" />
<div data-bind="foreachGrouped: { data: items, count: count }">
<h1 data-bind="html: $root.header"></h1>
<ul data-bind="foreach: $data">
<li data-bind="text: $data"></li>
</ul>
</div>
And here is the code used to wire up the view model:
ko.applyBindings({
header: ko.observable("Group Header"),
items: ko.observableArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
count: ko.observable(4)
});
Example: http://jsfiddle.net/dk1do2vr/2/