<div data-bind="myHandler, visible: !enabled()"> </div>So in general, you have access to all the other bindings when inside a bindinghandler:
ko.bindingHandlers.myHandler = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var visible = allBindings().visible;
}
};
The problem with calling allbindings().someBinding, is that you get the *result* of the binding.
In my case, I wanted to subscribe to when any updates happen to the entire binding: "visible: !enabled()"
Knockout handles this for a normal bindingHandler in the update function. If the valueAccessor changes, update gets fired.
So I needed to have a way to get access to the valueAccessor of a different bindingHandler on the same node. The solution I came up with involved asking the knockout bindingProvider to give me the value accessors, then subscribing to the valueAccessor I wanted to listen to:
ko.bindingHandlers.myHandler = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var bindingAccessors = ko.bindingProvider.instance.getBindingAccessors(element, bindingContext),
visibleAccessor = bindingAccessors.visible,
myObservable = viewModel.someObservable; // For complex reasons, this observable needs to update based on another binding in the same node
if (visibleAccessor) {
// This simulates what the knockout update bindingHandler does:
ko.computed(function() {
myObservable(ko.unwrap(visibleAccessor)); // the computed fires because we have visibleAccessor in our scope
});
}
}
};
So now when the visible binding updates, we get the result of the valueAccessor instead of a single result at one point in time of a valueAccessor (shown in the first js code block).
I know this sounds complicated, but this was exactly what I was looking for to be able to access the valueAccessors of the same node. Using allBindings().someHandler was forcing me to make trivial pureComputed variables:
var MyViewModel = function() {
this.enabled = ko.observable(false);
this.disabled = ko.pureComputed(function() {
return !this.enabled();
}, this);
}
I really wanted this trivial code to exist in the template, not in the viewModel. So the solution using getBindingAccessors allows me to keep this code in the templates.