2

I am stumped by the following behavior in a custom binding of knockout.js:

ko.bindingHandlers.customBinding = {
    update: function(element, valueAccessor, allBindingsAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        console.log( JSON.stringify(value) );
    }
}

ko.applyBindings({
    someText: ko.observable("inital value")
});

and

<input type="text" data-bind="value: someText, customBinding: {some: 'option'}">

The valueAccessor() should give me the view model property that is bound to the value of the element (i.e. the observable someText). To quote the docs:

valueAccessor — A JavaScript function that you can call to get the current model property that is involved in this binding. Call this without passing any parameters (i.e., call valueAccessor()) to get the current model property value.

However, what it really does is return the binding value, i.e. {some: 'option'}.

What am I missing?

See http://jsfiddle.net/j5y8H/

JotaBe
  • 38,030
  • 8
  • 98
  • 117
Tomalak
  • 332,285
  • 67
  • 532
  • 628

2 Answers2

1

You need to pass the model property you want for your valueAccessor in your custombinding call. In your case, you want the model property 'someText' :

<input type="text" data-bind="value: someText, customBinding: someText">

See http://jsfiddle.net/j5y8H/1/

Rune Vejen Petersen
  • 3,201
  • 2
  • 30
  • 46
  • 1
    Ah I see. That makes sense. It does not work the way I expected it, but it's consistent with the way the `value` binding works, for example. It's just not consistent with the way the documentation states it. `valueAccessor` will be whatever you care to pass in the binding, not necessarily the "the current model property". Thanks. – Tomalak Mar 21 '13 at 13:25
  • Yeah. Anything else you pass along you can pick up from the allBindingsAccessor. I've made a quick example where I pass along a string in a property called 'source' here : http://jsfiddle.net/j5y8H/3/ (or you can pick up the 'value' property like Grim points out) – Rune Vejen Petersen Mar 21 '13 at 13:38
1

You're mixing things up a bit - the valueAccessor parameter gives access to the value of your binding (like you found out already).

The "value" binding, on the other hand, is just another binding that might not even be present on the element where yours is applied - or not be valid at all (e.g. on a div).

If you really want to access the property that is bound to the value binding (and most likely if you do you might want to rethink your binding handler), you can do so through the allBindingsAccessor parameter, like that:

ko.utils.unwrapObservable(allBindingsAccessor().value);
Grim
  • 1,608
  • 9
  • 12
  • 1
    Yes, I found that one as well by now. :-) In fact I was mislead by the documentation, or rather I misread it. My plan is to build a custom binding that creates a jQueryUI datepicker (for example) and I'd like to inject an object into the binding that contains options for it. Much like the `template` binding works. – Tomalak Mar 21 '13 at 13:48
  • I don't know how jQuery datepicker workse, but i did something similar for some MooTools date picker addon, and i found out that handling the value updates and events directly within my handler, bypassing completely the use of the value binding, lead to much less headaches. :) – Grim Mar 21 '13 at 14:09