3

我有一个 Knockout 自定义绑定处理程序,我想在其中调用 foreach 绑定功能,然后调用回调函数。我不断收到“未捕获的错误:您不能将绑定多次应用于同一个元素。”现在我尝试执行此操作时出现错误。

我的自定义绑定非常简单(打字稿):

/// <reference path="knockout.d.ts" />
ko.bindingHandlers["postForeach"] = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        if (!allBindingsAccessor().postForeachCallback)
            throw "Callback not defined for postForeach binding!";

        //call foreach init functionality
        ko.bindingHandlers['foreach'].init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            //call foreach update functionality
            ko.bindingHandlers['foreach'].update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
            //call callback
            allBindingsAccessor().postForeachCallback();
    }
};

在构建这个时我有什么遗漏吗?

谢谢!

编辑:

回调函数

self.populateMainContentWindow = function () {
                    var dataTable = $(this.tableId).dataTable();
        dataTable.fnDestroy();

                // create the datatable
                        var actualTable = this.jQuery(this.tableId);
        if (actualTable.length == 0) {
            return false;
        }

        // create the data table with options
        var newDataTable = actualTable.dataTable(this.options);

        // always set the width afterwards
        actualTable.css("width", "100%");
            };

数据绑定签名(在“with”绑定中):

postForeach: array, postForeachCallback: $parent.viewModel().populateMainContentWindow
4

3 回答 3

6

Knockout 使用 的返回值init来确定它是否应该处理元素的后代。您可以只返回foreach.init函数的值,也可以专门{ controlsDescendantBindings: true }init函数返回:

init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    if (!allBindingsAccessor().postForeachCallback)
        throw "Callback not defined for postForeach binding!";

    //call foreach init functionality
    return ko.bindingHandlers['foreach'].init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
},

参考: http: //knockoutjs.com/documentation/custom-bindings-controlling-descendant-bindings.html

于 2013-09-14T02:07:54.947 回答
2

变体 1
我认为您当前的绑定看起来像

data-bind="foreach: someArray, postForeach: ..."  

您可以设置value绑定foreach内部postForeach绑定。例如:

data-bind="postForeach : 
           {postForeachCallback : function()
                                  {
                                    alert('After')
                                  },
           foreach: someArray}" // this is your old foreach  

捆绑:

ko.bindingHandlers["postForeach"] = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        if (!valueAccessor().postForeachCallback)
            throw "Callback not defined for postForeach binding!";

        //call foreach init functionality
        return ko.bindingHandlers['foreach'].init(element, valueAccessor().foreach, allBindingsAccessor, viewModel, bindingContext);
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            //call foreach update functionality
            ko.bindingHandlers['foreach'].update(element, valueAccessor().foreach, allBindingsAccessor, viewModel, bindingContext);
            //call callback
            valueAccessor().postForeachCallback();
    }
};  

JSFiddle 演示

变体 2
此变体视图模型 ( innerViewModel) 位于视图模型中。此视图模型与with绑定绑定。
现在data-bind看起来像

data-bind="postForeach : true, postForeachCallback : $parent.postCallback, foreachEx: values"  

视图看起来像

<div data-bind="with: innerViewModel">
   <ul data-bind="postForeach : true, postForeachCallback : $parent.postCallback, foreachEx: values">
       <li data-bind="text: val"></li>
   </ul>
</div>

JSFiddle 演示

于 2013-09-16T07:55:48.337 回答
1

它看起来与您发布的代码没有任何关系。相反,看起来有多个对 applyBindings 的调用,其中两个调用了同一个元素。

示例: http: //jsfiddle.net/tlarson/bFKuL/ (在控制台中查找错误)

var vm = {
    Name: "George"
}
ko.applyBindings(vm);
ko.applyBindings(vm);

标记:

<div data-bind="text:Name"></div>

为了解决这个问题,不要在同一个元素上调用 applyBindings 两次。为了帮助您准确了解如何使用您的代码执行此操作,我们需要查看更多您的代码,例如演示问题的小提琴。

于 2013-09-21T03:40:52.480 回答