Reputation: 34198
I saw a piece of code regarding Knockout and went through it but I could not understand how this code works. Here is the complete code for binding a normal method with a Knockout viewmodel.
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="Scripts/knockout-2.2.1.js"></script>
<script src="Scripts/jquery-1.7.1.js"></script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input type="button" data-bind="click: callalert" name="knockoutbtn" value="Call Knockout Method"/>
<input type="button" name="normalbtn" id="nbtn" value="Call Normal Method"/>
<script type="text/javascript">
var callmethod = function () { //Normal Method which would be
alert('hello'); //called from knockout binding
} //also from the normal button click
$(document).ready(function () { //Binded the Method with normal button
$("#nbtn").live("click", callmethod);
});
ko.applyBindings({ //Binded the method with ko view model
callalert : callmethod
});
</script>
</div>
</form>
</body>
</html>
I just do not understand what the meaning of this code is: data-bind="click: callalert"
and also do not understand this code:
ko.applyBindings({ //Binded the method with ko view model
callalert : callmethod
});
It seems that when the user clicks on the first button then a method will be called named callalert
but in the code there is no method named callalert
. When the user clicks on the second button, then a method will be called named callmethod
.
So please help me to understand the above code. Especially these two points
1) data-bind="click: callalert"
2) ko.applyBindings({ //Binded the method with ko view model
callalert : callmethod
});
suppose if anyone just see it below
var person = {
firstName: 'John',
lastName: 'Doe',
sayHi: sayHiFunction,
pets: ['Cat', 'Dog']
};
then how anyone would understand that sayHiFunction is a function because there is no bracket like sayHiFunction() ?
if you look the above code then u can see
$(document).ready(function () { //Binded the Method with normal button
$("#nbtn").live("click", callmethod);
});
that callmethod is calling by jquery code. so why twice it is define in code that callmethod need to be called when user click on button. once it is done by jquery and once it is done by knockout binding ? can u explain in detail.
if i remove the jquery portion then callmethod will be called when user click on button. waiting for your answer. thanks
Upvotes: 0
Views: 804
Reputation: 14108
Javascript objects
{ callalert : callmethod }
is a regular javascript object with one property: callalert
. In JS, you can construct objects in a key-value-pair fashion:
var person = {
firstName: 'John',
lastName: 'Doe',
sayHi: function() {
alert('Hi!');
},
pets: ['Cat', 'Dog']
};
This constructs an object that we put in a variable person
and give four properties: two normal properties (of string type), one function and on array.
Because in JS, functions are also objects, you can put them in variables and use them as such. So you can define a function and put it in a variable (as you are doing with your callmethod
variable) and then assign it to a member of an object (as you are doing with the callalert
property).
This would also work in my example:
var sayHiFunction = function() {
alert('Hi!');
};
var person = {
firstName: 'John',
lastName: 'Doe',
sayHi: sayHiFunction,
pets: ['Cat', 'Dog']
};
Knockout applyBindings
Next,
ko.applyBindings
accepts a javascript object. Usually, you would use an object with observable properties (properties handled by Knockout), but you can also have functions in it.
In your case, you only have a function. The implementation of the function is callmethod
and the identifier to call is callalert
.
So if you would do:
var myVariable = { callalert : callmethod };
myVariable.callalert();
you would get the alert. You've effectively created an object with one member (callalert
) which is a function (with the implementation of callmethod
), and put it in myVariable
.
Knockout data-bind
Now, what data-bind="click: callalert"
does is let Knockout know it should databind the click
event to the callalert
property of your viewmodel (the object you passed to applyBindings
). So when you click on the button, Knockout will call the callalert method on the viewmodel.
Update - jQuery
The jQuery code is indeed more readable. But when you have complex UIs, it will often require a lot of jQuery code (for hiding, showing, updating, etc controls). This can easily become hard to maintain and read. For this, Knockout and its MVVM approach can help.
The reason the code has it twice, is for showing the difference I believe. The first button used Knockout to call the method, the second button uses jQuery.
Both are valid approaches. In fact, I'd recommend jQuery if it's just that simple. But if you have more complex UIs, or if your project uses it in other screens, you might want to go with Knockout.
As for
how anyone would understand that sayHiFunction is a function because there is no bracket like sayHiFunction() ?
You can't immediately, but you know it's a variable, so if you look for the variable, you'll find out. But unless you need to set the implementation of the function dynamically at runtime, you'd have no reason to write it like this. You'd write the function inline:
var person = {
sayHi: function() {
alert('Hi');
}
}
But even then, you can still change it:
person.sayHi = function() {
alert('Hello!');
}
This makes JS a powerful language, but indeed not always easy to read for beginners.
Upvotes: 3