My Windows 8.1 App was working fine on Knockout 2.3 but after updating to 3.3 it seems like I get the wrong Context in my custom binding.
First here is how I apply binding for individual elements in the command bar of my app :
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);
}
}
});
Here is my custom binding code
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);
}
};
The problem is in:
ko.bindingHandlers.enable.update.call(this, element, command.canExecute, allBindingsAccessor);
canExecute
is undefined which I think is because I am not getting the right context in the init
and update
handlers. So what am I doing wrong in my code? Again the code was working in Knockout 2.3 , so could it be a Knockout issue?
UPDATE:
I created jsFiddle to show the problem. It contains the definition for ko.command
because I thought that could be the cause of problem
JSFiddle
The error is caused because Knockout 3.x binds to functions differently. In 2.x, you could bind directly to a function, but in 3.x, Knockout calls the function to get the viewmodel. You can still bind to a function in Knockout 3.x, but you'll need to wrap it in an observable or in another function.
ko.applyBindings(function() { return commandWrapper }, element);
来源:https://stackoverflow.com/questions/33635396/custom-binding-not-working-updating-from-knockout-2-3-to-3-3