我有一个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
答案 0 :(得分: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
答案 1 :(得分: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();
}
};
变体2
视图模型中的此varian视图模型(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>
答案 2 :(得分:1)
它看起来与您发布的代码无关。相反,看起来有多次调用applyBindings,其中两个调用同一个元素。
示例:http://jsfiddle.net/tlarson/bFKuL/ (在控制台中查看错误)
var vm = {
Name: "George"
}
ko.applyBindings(vm);
ko.applyBindings(vm);
标记:
<div data-bind="text:Name"></div>
要解决此问题,请不要在同一元素上调用applyBindings两次。为了帮助您确切了解如何使用代码执行此操作,我们需要查看更多代码,例如演示此问题的小提琴。