jump to navigation

Getting KO’ed with KnockoutJS August 31, 2012

Posted by ActiveEngine Sensei in ActiveEngine, Ajax, Approvaflow, ASP.Net, DataTables.Net, jQuery, New Techniques, Open Source.
Tags: , , , , ,
trackback

ImageOn the quest to provide a rich user interface experience on his current project, Sensei has been experimenting with KnockoutJS by Steve Sanderson.  If you haven’t reviewed it’s capabilities yet  it would be well worth your while.  Not only has Steve put together a great series of tutorials, but he has been dog fooding it with Knockout.  The entire documentation and tutorial set is completed used Knockout.  Another fine source is Knockmeout.net by Ryan Niemeyer.  Ryan is extremely active on StackOverflow answering questions regarding Knockout, and also has a fine blog that offers very important insight on developing with this framework.

KnockoutJS is a great way to re-organize your client side code.  The goal of  this post is not to teach you KnocoutJS; rather, Sensei wants to point out other benefits – and a few pitfalls – to adopting its use.  In years past, it’s been difficult to avoid writing spaghetti code in Javascript.  Knockout forces you to adopt a new pattern of thought for organizing your UI implementation.  The result is a more maintainable code base.  In the past you may have written code similar to what Sensei use to write.  Take for example assigning a click event to a button or href in order to remove a record from a table:

<table>
  <thead></thead>
  <tbody>
    <tr>
      <td><a onclick="deleteRecord(1); return false;" href="#">Customer One</a></td>
      <td>1313 Galaxy Way</td>
    </tr>
    <tr>
      <td><a onclick="deleteRecord(2); return false;" href="#">Customer Two</a></td>
      <td>27 Mockingbird Lane</td>
    </tr>
</tbody>
</table>

<script type="text/javascript">
function deleteRecord(id){
  //  Do some delete activities ...
}
</script>

You might even went as far as to assign the onclick event like so:

$(document).ready(function(){
  $("tr a").on('click', function(){
    //  find the customer id and call the delete record
  });
});

The proposition offered by Knockout is much different.  Many others much more conversant in design patterns and development than Sensei can offer better technical reasons why you sound use Knockout.  Sensei likes the fact that it makes thinking about your code much simpler.  As in:

 
<td><a data-bind="click: deleteRecord($data)" href="#">Customer One</a></td>

Yep, you have code mixed in with your mark up, but so what.  You can hunt down what’s going on, switch to your external js file to review what deleteRecord is supposed to do.  It’s as simple as that.  Speaking of js files, Knockout forces you to have a more disciplined approach organizing your javascript.  Here is what the supporting javascript could look like:

var CustomerRecord = function(id, name){
  //  The items you want to appear in UI are wrapped with ko.observable
  this.id = ko.observable(id);
  this.name = ko.observable(name);
}

var ViewModel = function(){
var self = this;
  //  For our demo let's create two customer records.  Normally you'll get Json from the server
  self.customers = ko.observableArray([
    new CustomerRecord(1, "Vandelay Industries"),
    new CustomerRecord(2, "Wiley Acme Associates")
  ]);

  self.deleteRecord = function(data){
    //  Simply remove the item that matches data from the array
    self.customers.remove(data);
  }
}

var vm = new ViewModel();
ko.applyBindings(vm);

That’s it.  Include this file with your markup and that’s all you have to do.  The html will change too.   Knockout will allow you to produce our table by employing the following syntax:

<tbody data-bind=”foreach: customers”>
<tr>
<td><a href=”#” data-bind=”click:  deleteRecord($data)”><span data-bind=”text: id”></span></a></td>
<td><span data-bind=’text: name”></span></td>
<tr>
</tbody>

These Aren’t the Voids You’re Looking For

So we’re all touchy feely because we have organization to our Javascript and that’s a good thing.  Here’s some distressing news – while Knockout is a great framework, getting the hang of it can be really hard.  Part of the reason is Javascript itself.  Because it’s a scripting language, you end up with strange scenarios where you have a property that appear to have the same name but different values.  You see, one of the first rules of using Knockout is that observables ARE METHODS.  You have to access them with (), as in customer.name(), and not customer.name.  In other words, in order for you to assign values to an observable you must:


customer.name("Vandelay Industries");

//  Don't do this - you create another property!!

customer.name = "Vandelay Industries";

What? Actually, as you probably have surmised, you get .name() and .name, and this causes great confusion when you are debugging your application in Firebug.  Imagine you can see that customer.name has a value when you hit a breakpoint, but its not what you’re looking for.  Sensei developed a tactic to help verify that he’s not insane, and it works simply.  When in doubt, go the console in Firebug and access your observable via the ViewModel; so in our case you could issue:

vm.customer.name();

When name() doesn’t match your expectation you’ve most likely added a property with a typo.  Check with

vm.customer.name;

It sounds silly, but you can easily spend a half hour insisting that you’re doing the right thing, but you really confusing a property with a method.  Furthermore, observable arrays can also be a source of frustration:

// This is not the length of the observable array. It will always be zero!!!
vm.customers.length == 0;

// You get the length with this syntax
vm.customers().length;

Knock ’em inta tamarra, Rocky

Had Sensei known the two tips before starting he would have save a lot of time.  There are many others, and they are best described by Ryan Niemeyer in his post 10 things to know about Knockout from day one.  Read this post slowly.  It will save you a lot of headache.  You may familiar with jQuery and Javascript, but Knockout introduces subtle differences that will catch you off guard.  That’s not a bad thing, it’s just different than what you may be used to.  Ryan also makes great use of JS Fiddle and answers most of his StackOverflow questions by using examples.  Those examples are in many cases easier to learn from than the tutorial since the scope is narrower than the instruction that Steve Sanderson gives.  It really allows you play along as you learn.

Comments»

1. victorantos - October 1, 2012

You provided a simple example that demonstrates the simplicity of koJS

I tried going further and after a few weekends I have done my first online game. It’s a wordsearch puzzle, and I am very proud of my “javascript” skills at this moment 🙂

ActiveEngine Sensei - October 2, 2012

Awesome to hear!!!! I have found that KnockoutJS has really altered my thinking when it comes to client side solutions, and I mean radically altered my thinking. In some senses – and I’m going way out on a limb here, so take it with a grain of salt – you could make the case that you could get away with a simple web service (.asmx), no code behind and html files. I mean craft a domain solution, test it like always, include the assembly in the web application and expose the endpoints via the web service.

Like I said, I’m a little way out there, and maybe inexperienced with supporting enterprise level applications, but I’m tellin’ ya’ your clients will love it when you can give them rich functionality quickly. Then they’ll be forgiving when some stuff will take a little longer ’cause you give ’em them apps they love to use.

Thanks for reading. Rock on with the KnockoutJS and share some more of your adventures.

2. Dave Snijder - October 30, 2012

I’m really diggin’ Knockout. Of all the JS frameworks, this was the one that I picked up the most easily. This was thanks to the interactive tutorial and the many examples that are available on the knockoutjs website.

The pointers and links in this post are helping a bunch as well. Thanks!

ActiveEngine Sensei - October 30, 2012

Glad these were of use to you. As great as the framework is there are times when I get de-railed. I guess it’s the same with anything else – good and bad to all tool sets.

Have you checked knockmeout.net? It’s run by Rick Niemeyer who is really active on StackOverflow answering knockoutjs questions. I truly a lot from him, as he as a ton of js-fiddles.


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 )

Connecting to %s

%d bloggers like this: