自定义绑定无法从 Knockout 2.3 更新到 3.3
Custom Binding not working updating from Knockout 2.3 to 3.3
我的 Windows 8.1 应用程序在 Knockout 2.3 上运行良好,但在更新到 3.3 后,我的自定义绑定中似乎出现了错误的上下文。
首先是我如何在我的应用程序的命令栏中为单个元素应用绑定:
var cmdArray = [];
var commandIsRunning = function() {
return _.any(cmdArray, function(command) {
return command.isRunning();
});
};
_.each(_bottomCommands, function (row) {
if(row.command) {
// command wrapper
var commandWrapper = ko.command({
action: function() {
var rowCommand = row.command();
if (rowCommand) {
return rowCommand();
}
return WinJS.Promise.as();
},
canExecute: function() {
var rowCommand = row.command();
if (rowCommand) {
return rowCommand.canExecute() && !commandIsRunning();
}
return false;
}
});
cmdArray.push(commandWrapper);
//Bind the command
var element = document.querySelector('#' + row.id);
if (element) {
element.setAttribute('data-bind', 'command: $data');
ko.applyBindings(commandWrapper, element);
}
}
});
这是我的自定义绑定代码
ko.bindingHandlers.command = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var command = ko.utils.unwrapObservable(valueAccessor());
ko.bindingHandlers.click.init.call(this, element, ko.observable(command), allBindingsAccessor, viewModel, bindingContext);
},
update: function (element, valueAccessor, allBindingsAccessor) {
var command = ko.utils.unwrapObservable(valueAccessor());
ko.bindingHandlers.enable.update.call(this, element, command.canExecute, allBindingsAccessor);
}
};
问题出在:
ko.bindingHandlers.enable.update.call(this, element, command.canExecute, allBindingsAccessor);
canExecute
未定义,我认为这是因为我没有在 init
和 update
处理程序中获得正确的上下文。那么我的代码做错了什么?代码再次在 Knockout 2.3 中运行,所以它可能是 Knockout 问题吗?
更新:
我创建了 jsFiddle 来显示问题。它包含 ko.command
的定义,因为我认为这可能是问题的原因
JSFiddle
错误是因为 Knockout 3.x 绑定到不同的功能。在 2.x 中,您可以直接绑定到一个函数,但在 3.x 中,Knockout 调用函数来获取视图模型。您仍然可以在 Knockout 3.x 中绑定到一个函数,但您需要将其包装在一个可观察对象或另一个函数中。
ko.applyBindings(function() { return commandWrapper }, element);
我的 Windows 8.1 应用程序在 Knockout 2.3 上运行良好,但在更新到 3.3 后,我的自定义绑定中似乎出现了错误的上下文。
首先是我如何在我的应用程序的命令栏中为单个元素应用绑定:
var cmdArray = [];
var commandIsRunning = function() {
return _.any(cmdArray, function(command) {
return command.isRunning();
});
};
_.each(_bottomCommands, function (row) {
if(row.command) {
// command wrapper
var commandWrapper = ko.command({
action: function() {
var rowCommand = row.command();
if (rowCommand) {
return rowCommand();
}
return WinJS.Promise.as();
},
canExecute: function() {
var rowCommand = row.command();
if (rowCommand) {
return rowCommand.canExecute() && !commandIsRunning();
}
return false;
}
});
cmdArray.push(commandWrapper);
//Bind the command
var element = document.querySelector('#' + row.id);
if (element) {
element.setAttribute('data-bind', 'command: $data');
ko.applyBindings(commandWrapper, element);
}
}
});
这是我的自定义绑定代码
ko.bindingHandlers.command = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var command = ko.utils.unwrapObservable(valueAccessor());
ko.bindingHandlers.click.init.call(this, element, ko.observable(command), allBindingsAccessor, viewModel, bindingContext);
},
update: function (element, valueAccessor, allBindingsAccessor) {
var command = ko.utils.unwrapObservable(valueAccessor());
ko.bindingHandlers.enable.update.call(this, element, command.canExecute, allBindingsAccessor);
}
};
问题出在:
ko.bindingHandlers.enable.update.call(this, element, command.canExecute, allBindingsAccessor);
canExecute
未定义,我认为这是因为我没有在 init
和 update
处理程序中获得正确的上下文。那么我的代码做错了什么?代码再次在 Knockout 2.3 中运行,所以它可能是 Knockout 问题吗?
更新:
我创建了 jsFiddle 来显示问题。它包含 ko.command
的定义,因为我认为这可能是问题的原因
JSFiddle
错误是因为 Knockout 3.x 绑定到不同的功能。在 2.x 中,您可以直接绑定到一个函数,但在 3.x 中,Knockout 调用函数来获取视图模型。您仍然可以在 Knockout 3.x 中绑定到一个函数,但您需要将其包装在一个可观察对象或另一个函数中。
ko.applyBindings(function() { return commandWrapper }, element);