Knockout click event knocking you out

Here is my simple viewmodel:

knockoutBindingViewModel

here is a simple html

knockoutBindinghtml

When I open this html in browser, I see removePerson method is called again and again, in fact all three times. Looks like whenever I bind a value of ‘people’ to html,  knockout calls removePerson. I don’t want this repeated call to ‘removePerson’, I want it to be called only on click, not on every bind.

Digging little deeper into knockout, you will find that ko registers the event and because of $data binding context, ko calls the removePerson again and again for every binding. So what is the solution?

Turns out that solution is simple, just remove $data from removePerson method and ko will stop calling this method for every binding.knockoutBindinghtml2

However, you may wonder once you have removed $data context from removePerson, then how your method will know about the person to be removed?

Here comes the ko magic, when ko calls the click method it automatically passes two arguments, first one is the current model value, which will point to the exact person and second one is event object. Read here more.

Once this repeated function call problem is solved, you get into another problem and you realize that your ‘anotherFunction’ is not called and in browser debugger window you find an error.

knockoutBindingError

The error says: Uncaught TypeError: undefined is not a function.

Before you go any further, Read this section again and see if you can find the source of  error.

What happens here is ko calls removePerson in eventHandler context which changes the meaning of “this”. You can see the value of ‘this’ in debugger. The documentation suggest you use ‘self’ or other variables and refer it in the function in place of ‘this’, and don’t be dependent on the ‘this’ value. But, if you are using typescript then you are stuck and isn’t typescript suppose to save you from ‘this’ and ‘self’ funny javascript behavior.

It turns out that there is another easy solution, to preserve the value of ‘this’ in typescript you should use lambda syntax. Just change the function as follows:

knockoutBindingViewModel2

This syntax of typeScript preserve the value of this. Read here how typeScript saves you from ‘this’ and ‘that’ of JavaScript.

Interestingly all this solution is simple once you know it, but if you don’t know,  you may break your head for hours, like I did :) hopefully it will save you some headache of ko and typeScript mood swings.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s