Today I’m spending my hour on Knockout. I’ve read some blog posts about Knockout and I listened to a podcast the other day but I’ve never done any coding with Knockout so I started with the tutorials on http://learn.knockoutjs.com/.
Knockout uses the Model-View-ViewModel pattern, more about that later. Right now I don’t care about the details behind.
As you will notice there’s not much code in here. Since I’m running through the tutorials I don’t want to copy their code. If you’re interested in starting with Knockout I suggest you try out the tutorials, they are great!
The GUI of the tutorial is great. You get instructions, a code window with a view with HTML markup, a code window with a viewmodel and an output window.
The introduction tutorial explains some basic stuff about data binding, views and viewmodels. Just by putting things like data-bind=”text: firstName” in our html elements we have connected our viewmodel and will display the values from the model. Now, this is not earth shattering, we’ve done data binding in ASP.NET for a long time.
In order to update a field we add observables in our viewmodel, i.e. ko.observable(“Patrik”). When an input field and a display field are both data bound to the same value the display will automatically update as soon as you update the input field. They stay in sync because of automatic dependency tracking. That’s very cool!
To our viewmodel we can also add computed values where we create a function that for example concatenates other viewmodel data.
One other thing in this tutorial that really made me smile was to see how easy it was to add behavior with functions. We add the function capitalizeLastName to the viewmodel, a function that will get the current value of LastName and write back that value in upper case. Then we add a button with data-bind=”click: capitalizeLastName” and we’re done. How easy is that?!
The introduction illustrates the key points of MVVM.
- A clean, object-oriented representation of your UI’s data and behaviors (the viewmodel)
- Separately a declarative representation of how it should be displayed visibliy (the view)
- Arbitrarily sophisticated behaviors can be implemented just by updating the viewmodel object. No need to worry about which DOM elements need to be changed/added/removed.
Going on with the next tutorial, working with lists and collections.
We’ve already been introduced to observables and now we can use an observable array. Using these arrays and a foreach binding we can easily add or remove elements to an array and our view will be updated instantly.
I still have time left so I jump into a tutorial on Single Page Applications which demonstrates navigation within the page.
It give a short explanation of hash-based and pushState navigation. Hash-based will add e.g. #category=shoes to the URL and add this to the browser history. The page will not reload but the scripts running in the page will get the hash and run the Ajax requests. pushState is an HTML5 API that offers a different way to change the current URL without triggering a reload. Instead of updating the hash we can update the entire URL.
In the tutorial we use hash-based navigation and build a simple mail client. We’re only building the client-side user interface, we don’t know anything about getting data yet.
Using the basics we’ve already learned we can display a list of folders (array and foreach) and adding behaviors (functions) to our viewmodel each folder display different data when clicked.
There are many librarians for client-side navigation, here we use sammy.js. Client-side URL patterns are then defined in the viewmodel for Sammy. Instead of triggering Ajax requests clicking on the folders and rows will trigger client-side navigation. Sammy will detect the client-side navigation and then do the Ajax requests as before and update the viewmodel state. The back and forward buttons of the browser will work great since the hashed URL is put into the browser history.
I see that it may be a lot of work defining the url patterns for Sammy if you have a large application but I think it’s worth it considering how smooth everything is. Since all the rendering is done client-side and the only raw JSON data is being transmitted to and from the server it will also be very fast and light.
Well, one hour is up and I’m totally blown away by Knockout! I’m really looking forward to taking a deeper look and learn how to integrate this with my server-side code.