Javascript 淘汰自定义绑定处理程序:$root未定义

Javascript 淘汰自定义绑定处理程序:$root未定义,javascript,knockout.js,Javascript,Knockout.js,我使用的是一个敲除自定义绑定处理程序(借用自)。在嵌套标记中,我希望引用位于视图模型根上的可观察对象。但是绑定失败,因为$root未定义。同样的标记也适用于标准的foreach绑定。我不知道为什么自定义hander阻止使用$root 以下是绑定处理程序的源代码: ko.bindingHandlers.foreachGrouped = { init: function(element, valueAccessor) { var groupedItems, options

我使用的是一个敲除自定义绑定处理程序(借用自)。在嵌套标记中,我希望引用位于视图模型根上的可观察对象。但是绑定失败,因为$root未定义。同样的标记也适用于标准的foreach绑定。我不知道为什么自定义hander阻止使用$root

以下是绑定处理程序的源代码:

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 };
}
};

示例:

问题在于原始bindingContext在处理程序中丢失。因此,当调用
ko.applyBindingsToNode()
时,它使用一个全新的上下文(该上下文为空)。处理程序早在能够指定绑定上下文是什么的时候就被添加到了更高版本的knockout中。您需要对处理程序进行调整,以便能够保留该上下文

ko.applyBindingsToNode(element, { foreach: groupedItems }, bindingContext);
因此,您需要在处理程序中进行调整(删除不相关的位以便于查看):

ko.applyBindings({
  header: ko.observable("Group Header"),
      items: ko.observableArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
      count: ko.observable(4)
});
ko.applyBindingsToNode(element, { foreach: groupedItems }, bindingContext);
ko.bindingHandlers.foreachGrouped = {
    // need to get the binding context (fifth param)
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        //...

        //use the normal foreach binding with our new computed
        ko.applyBindingsToNode(element, { foreach: groupedItems }, bindingContext); // pass in the binding context

        //...
    }
};