Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
KnockoutJS Web Development

You're reading from   KnockoutJS Web Development Efficiently work with data, web templates, and custom HTML tags using KnockoutJS

Arrow left icon
Product type Paperback
Published in Feb 2015
Publisher
ISBN-13 9781782161028
Length 178 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
John Farrar John Farrar
Author Profile Icon John Farrar
John Farrar
Arrow right icon
View More author details
Toc

Using internal functions with Knockout

The applyBindings method in the previously explained bindings section uses a common structure. We included that example in case you cross code written in that style. It will help you understand it if you see it someone else's code that is using that approach. Another style of coding is to declare the Model with a function declaration. The DOM markup or View code does not change for either scenario. Let's convert our binding example to a functional declaration. Copy the binding.htm file and create a new file called functions.htm in the same folder. Here is the original declaration:

var viewModel = {
  myVariable: ko.observable()
  ,myHTML: ko.observable()
  ,myLeft: ko.observable()
  ,myRight: ko.observable()
  ,myBalance: ko.observable()
  ,isVisible: ko.observable()
};

Note that we could have set the values of the observables immediately along with the declaration. If we had done that it would have looked like this:

var viewModel = {
  myVariable: ko.observable("Awesome simple!")
  ,myHTML: ko.observable("<strong>Awesome</strong> simple!")
  ,myLeft: ko.observable("pullLeft")
  ,myRight: ko.observable("pushRight")
  ,myBalance: ko.observable(-47.23)
  ,isVisible: ko.observable(true)
};

We are doing this to tighten our code for the sake of the book. You should use good logic when choosing which way to do this in your code. There are times where using this style of coding is important, but often it is just a matter of the coder's style. Beware of letting your style keep you from considering which one is best as you write the code.

Now we will look at moving the code over to a functional declaration. We start, of course, with a different kind of declaration because it is a function as appears here:

function viewModel() {
// add declarations here}

It would be equally valid to declare the ViewModel as follows. There is no significant difference:

viewModel = function() {
// add declarations here}

Now, we will look at adding our ViewModel items back in. In the structured approach we just described, the items were entered as collection items with the classic comma separator. In this model, each item is a parameter and is terminated by a semi-colon:

viewModel = function() {
this.myVariable = ko.observable("Awesome simple!");
this.myHTML = ko.observable("<strong>Awesome</strong> simple!");
this.myLeft = ko.observable("pullLeft");
this.myRight = ko.observable("pushRight");
this.myBalance = ko.observable(-47.23);
this.isVisible = ko.observable(true);}

Note that we declared each of these items with the this scope declaration, which refers to the ViewModel object. When programming in JavaScript, it is common practice to alias this to avoid scope confusion. We will rewrite the previous code one more time using self rather than this as the base scope:

viewModel = function() {
  var self = this;
self.myVariable = ko.observable("Awesome simple!");
self.myHTML = ko.observable("<strong>Awesome</strong> simple!");
self.myLeft = ko.observable("pullLeft");
self.myRight = ko.observable("pushRight");
self.myBalance = ko.observable(-47.23);
self.isVisible = ko.observable(true);}

Tip

Note that we set the self variable using a var declaration. This prevents issues of external naming conflicts.

Now, if we run the page for functions.htm from our browser, it should run identical to our binding.htm file. Yet, there is a difference. This will help you understand why we introduced the developer tools where we did in the course. Open the tools and in the command prompt, enter viewModel.isHTML() to see what you get as a result:

Using internal functions with Knockout

Preventing hidden features

In the previous screenshot we obtained the what you might think is an unexpected result as the View is obviously bound to the ViewModel. The issue here is an issue of the concept of closure. You are welcome to explore more about closure if you wish but just realize it means parts of an object or the item contents are there but hidden. When this type of declaration is made in this style, you cannot interact with it from JavaScript. The declaration should have been made with new to create an object from the function as follows:

ko.applyBindings(new viewModel());

If you run the browser and try to connect to the ViewModel now, you will see that it is still having the same issue with closure. We found this is the best way to work around it at my company:

vm = new viewModel();
ko.applyBindings(viewModel);

Now, we will reference the Model using vm rather than viewModel and this is the result we will get:

Preventing hidden features

We see that by declaring the object outside the argument passed to our Knockout applyBindings method, we avoided the closure issue. This is not an issue when using the structured style of ViewModel declaration. Hopefully, this saves you from hours of wondering what is wrong with your code or if Knockout is broken. We will not answer how much time I burned on this the first time it occurred, but it was long after I started using Knockout. It says that even experts can make rookie mistakes. I humbled myself and asked the community for help, and the answer came pretty fast.

You have been reading a chapter from
KnockoutJS Web Development
Published in: Feb 2015
Publisher:
ISBN-13: 9781782161028
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime