KO click event fires on page load?

4,078 views
Skip to first unread message

michaelF

unread,
Apr 17, 2012, 3:38:04 PM4/17/12
to KnockoutJS
Hi

I am new to KO, trying out version 2.

The click event seems to fire on the page load, how can I avoid this?
I have my test model:

function theVM() {
var self = this;
self.firstName = ko.observable('Harry');
self.lastName = ko.observable('Smith');
self.fullName = ko.computed(function(){
return self.firstName() + ' ' + self.lastName();
});

};

and then a link in which I want to change the firstName (from the
initial 'Harry' to say 'Mary'):

<a href='#' data-bind="click: firstName('Mary')">click to change
name</a>

I would expect (and want) the initial first name to be Harry, ie:

The name is <span data-bind="text: fullName"></span>

would give 'Harry Smith' and then when I click the link it should
change to 'Mary Smith'. But in fact it is 'Mary Smith' from the start,
as if the click event fires in the page load or the DOM ready, which I
do not want. The ordinary javascript 'onClick' does not behave like
that.

How, using KO, would I achieve this?

If I have the link as something like:

<a href='#' onclick="theVM.firstName('Mary');">click to change name</
a>

then the initial name IS 'Harry Smith' (as I want), but then clicking
the link does not change the firstName to Mary. Why not?

Thanks

-- Mike

rus...@searus.co.uk

unread,
Apr 17, 2012, 4:24:14 PM4/17/12
to knock...@googlegroups.com
Hi,
 
This is because the click that you have defined is evaluated when it is parsed by knockout, meaning that the firstName("Mary") is called when the data-bind is parsed.
 
You can wrap the click in a function to get round this: <a href='#' data-bind="click: function(){ firstName('Mary'); }">click to change
name</a>
But, it may be neater to update your view model to have an update method and a new textbox for the new value:
 
<input data-bind="value: newFirstName"/>
<a href='#' data-bind="click: updateFirstName;">click to change
name</a>
 
function theVM() {
var self = this;
self.firstName = ko.observable('Harry');
self.lastName = ko.observable('Smith');
self.fullName = ko.computed(function(){
return self.firstName() + ' ' + self.lastName();
});
self.newFirstName = ko.observable('');
self.updateFirstName = function(){
  self.firstName(self.newFirstName());
  self.newFirstName('');
};

};
WARNING: this is untested code, but hopefully you get the idea.
 
Russell

michaelF

unread,
Apr 17, 2012, 5:50:11 PM4/17/12
to KnockoutJS
Thanks Russell, that is a great help.

I worked through both of your examples, and learned a lot.  Your
second and longer example all worked except the data-bind you had for
the click:

<a href='#' data-bind="click: updateFirstName;">

did not work with the semicolon, and I had to take it out:

<a href='#' data-bind="click: updateFirstName">

but that was learning too, as I only really learn when I have to fix
things!

Thanks again for your time and trouble, much appreciated

-- Mike
Reply all
Reply to author
Forward
0 new messages