Take the 2-minute tour ×

I have anchor tag like this

<a href="#" class="btn btn-success order-btn" data-bind="attr:{'data-tiername':$data.tierName, 'data-identifier' : $parent.identifier}, click: $root.setPath.bind($data,$data.tierName, $parent.identifier)">Send values</a>

In the viewmodel

var appViewModel = {
    setPath: function (data, tier, identifier) {

The result is some knockoutjs core code being displayed in alert message (possibly definitions of observable(),dependentObservable() functions and [Object object] which is empty when alerted with JSON.stringify)

why does this work?


but not this:


note that tierName is an observable(), identifier is computed()

Where can I find more about bind() ??

share|improve this question
add comment

2 Answers

up vote 4 down vote accepted

Since tierName and identifier are observables, you need to call them to access to their values:

click: $root.setPath.bind($data, $data.tierName(), $parent.identifier())

Also, first argument in bind will be bound to this in setPath, so I guess you need something like this:

click: $root.setPath.bind(/*will be bound to this*/ $root, $data, $data.tierName(), $parent.identifier())

Finally, if $data itself is an observable (which is not clear if it is from you code), then you need to call it as well:

click: $root.setPath.bind($root, $data(), $data().tierName(), $parent.identifier())

Also remember bind has been introduced in ECMAScript 5, so it may not be present in all browsers. So I would probably do something like this instead:

click: function(){$root.setPath($data, $data.tierName(), $parent.identifier());}

Here is additional info on bind.

share|improve this answer
i wanted to do alert(tier); alert(identifier); in my viewmodel function, i didnt really want the context(this). So my function became setPath(tier,identifier) Thanks for helping out –  nthapa13 Feb 24 '12 at 8:23
KO does add an implementation of bind if it is not available, so if you are referencing KO, then you are safe to use bind. –  RP Niemeyer Feb 24 '12 at 13:56
Thank you RP Niemeyer, it's good to know. –  Roman Bataev Feb 24 '12 at 14:17
add comment

The first parameter to bind is the target (what you want this to be) when your function is executed. So, if you want data to be the first argument, then it needs to be the second argument.

Inside your function, if you are dealing with observables or computed observables, then you need to unwrap them to see their value. You would do this either by calling it as a function alert(data()); or by calling alert(ko.utils.unwrapObservable(data)); (which is generally used when you don't know at design type if what you are going to be dealing with is an observable or a non-observable.

The reason that attr and other bindings work when you pass an observable/computed observable is that they all call ko.utils.unwrapObservable for you for convenience (so you don't have to add () when passing observables unless you are writing an expression !$data().

Here is some reference on bind: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

share|improve this answer
Thank you @RPN for the response,its really helpful. –  nthapa13 Feb 24 '12 at 8:22
add comment

Your Answer


