This blog post compares the same twitter search application written with both Knockout and Kendo in order to highlight the strengths and weaknesses of each framework.

knockout-vs-kendo

Introduction

I've always been a big fan of Knockout, most likely because it reminds me of Silverlight (rest in peace).

For my thoughts on how Silverlight and Knockout compare, head over to codeproject where I wrote quite a lengthy article on the subject.

More recently I have been dabbling with the use of Knockout for writing mobile applications. Because Knockout is an MVVM framework and doesn't have any UI components of its own, I used a combination of jQuery Mobile (jQM) and Knockout. I must admit, the integration of these two frameworks wasn't entirely painless!.

It is the integration pain I experienced with jQM and Knockout that has resulted in my interest in KendoUI.

KendoUI (www.kendoui.com) is a commercial JavaScript framework that includes web and mobile UI widgets together with an MVVM framework, which, on initial inspection, closely resembles Knockout. The promise of an MVVM framework and mobile widgets that play nicely together is quite appealing!

In order to compare Kendo with Knockout + jQM I re-implemented the twitter-search application that I blogged about a few months ago. The rest of this blog post is a collection of thoughts, commentary on the differences and personal opinions.

The two version of the code are available on github:

And you can see working examples at the following locations:

It is worth viewing the above on your phone.

From Knockout to KendoUI

Knockout has magic properties, Kendo has magic objects!

JavaScript does not support the notion of change-notification when you change the value of an object's properties. This is a vital feature for supporting binding within an MVVM framework, so both Kendo and Knockout have to provide this missing change notification.

With Knockout change notification is provided via observable properties:

var knockoutViewModel = {
  name : ko.observable("john")
};

When a property has been created via ko.observable you can subscribe to change notifications for that property.

With Kendo change notification is provided via observable objects:

var kendoViewModel = kendo.observable({
  name : "john"
});

And as a result you can subscribe to change notifications on the object..

Neither Kendo or Knockout are able to detect when a property is set directly, instead, you must set the property value via a function. With Knockout, your property is actually a function which you can set as follows:

knockoutViewModel.name("john smith"):

Whereas with Kendo you set the property via the owning object:

kendoViewModel.set("name", "john smith");

Both Kendo and Knockout support the concept of dependant properties, where you construct a property by composing one or more of the other objects properties, with change notifications happening automatically.

Both Kendo's object-centic and Knockout's property-centric approaches seem quite reasonable, but as we shall see later this small difference has an impact on many aspects of each framework.

Knockout is more flexible regarding view model construction

Because Knockout performs its 'magic' at the property level, it does not place any restrictions on the way in which you construct your view models. You can use the literal syntax:

var knockoutViewModel = {
  name : ko.observable("john")
};

Or define a constructor:

function KnockoutViewModel() {
  this.name = ko.observable("john");
}

var viewModel = new KnockoutViewModel();

Personally I like the second approach because it gives you a view model 'factory', i.e. you can create multiple instances of the same view model, and it also allows you to define both public and private functions:

function KnockoutViewModel() {
  this.name = ko.observable("john");

  saveState = function() {
    // do something here
  }

  this.update = function() {
    saveState();
  }
}

In the code above the saveState function is private - for more information on this pattern I'd recommend reading Private Members in JavaScript by Douglas Crockford.

All of the Kendo examples create view model using a literal syntax:

var kendoViewModel = kendo.observable({
  name : "john"
});

Initially I was under the impression that it wasn't possible to create Kendo view models using constructor functions, furthermore, one of the nice guys from the Kendo support rather apologetically told me "I am afraid that it is not possible to emulate Knockout style of view model creation via functions. Kendo MVVM supports only the literal style.".

However, after a little bit of thought, I realised that it is possible if you explicitly return an observable as follows:

function KendoViewModel() {
  this.name = "john";

  return kendo.observable(this);
}

var viewModel = new KendoViewModel ();

However, things are not quite so straightforward - if you need to capture the reference to 'this' you must ensure that the reference is to the observable object, as follows:

function KendoViewModel() {
  this.name = "john";

  function saveState = function() {
    console.log(that);
  }

  this.update = function() {
    saveState();
  }

  var that = kendo.observable(this);
  return that;
}

var viewModel = new KendoViewModel ();

In the above code the variable, that, is always going to refer to the observable object regardless of what, this, refers to.

Kendo requires a little effort to make it work with Intellisense

Following on from the previous point, because the Kendo 'magic' is at the object level, Visual Studio Intellisense becomes flummoxed. Now I know that Visual Studio is perhaps not the best tool for JavaScript, but I can bet that quite a few Knockout and Kendo developers use it!

Visual Studio uses pseudo-execution of your JavaScript code to provide Intellisense. With Knockout this works well out-of-the-box - see the image below where the update function, together with its 'summary' text, are picked up by Intellisense:

ko_intellisense

Whereas with Kendo, in order for Visual Studio to be able to execute your code it needs to be aware of the Kendo and jQuery JavaScript files. This can be done by adding a 'reference' comment, as shown below:

kendo_intellisense

Note that you can also see the other functions that are present on observable objects.

Knockout supports view model hierarchies

One particularly elegant feature of Knockout is that it supports view model hierarchies. When binding collections of objects, Knockout creates a child binding context that refers to the nested view model data. You can also explicitly set the binding-context of an element via the 'with' binding. This approach allows you to create complex nested view models.

With Kendo, when binding a collection of objects the 'context' for each item is the parent view model, which means that any event bindings are sent to the owning view model. This is clearly due to the way that Kendo uses observable objects rather than observable properties.

Whilst this is not a significant limitation, I do miss the binding-context concept when working with Kendo. The lack of this feature does mean that view models can become bloated.

Kendo bindings are not JavaScript!

With Knockout, bindings are JavaScript, which means you can have bindings which contain logic. For example:

data-bind="enable: searchTerm().length > 0 && isSearching() == false,
           click: search"

Kendo bindings are not JavaScript!

A simple way to achieve equivalent functionality is to move the JavaScript in the binding into a dependant property:

searchButtonDisabled: function () {
  return this.get("searchTerm").length === 0 && this.get("isSearching") === false;
}

Which is bound as follows:

data-bind="click: executeSearch, { disabled: searchButtonDisabled }"

I do not see this as a significant limitation of Kendo. I do use this feature quite often with Knockout, it feels a little like the Silverlight / WPF concept of value-converters. However, I can see how it could be abused, hiding JavaScript logic within bindings isn't terribly good for testing or maintenance!

Kendo lacks a $data binding

With Knockout, if you create a 'foreach' binding to an array of strings, the template that renders each string can make use of the $data binding:

<span data-bind="text: $data"></span>

The above is needed because the binding-context of the above span element is a string - we want to bind to the object itself rather than a property of the object.

I could not find an equivalent feature with Kendo, so had to create an object as a container for the string:

this.recentSearches.unshift({ searchString: this.searchTerm });

And bind it as follows:

<span data-bind="text:searchString"></span>

Again, a pretty minor limitation.

Kendo has its own UI widgets!

So far much of my discussion has focussed on Knockout features which Kendo does not support. However, Kendo is much more than just an MVVM framework, it includes a large number of web and mobile UI widgets.

In the context of this comparison, I integrated jQM with Knockout to create my mobile UI - and as I mentioned earlier, this integration was pretty painful. In contrast, the Kendo UI Mobile framework integrates seamlessly with the Kendo MVVM framework - as you might expected!

Kendo UI does not mangle the DOM

While we are on the subject of the UI, one of the features of jQM that I really disliked is the way that it totally mangles the DOM.

In order to support the jQM styling it requires a large number of 'supporting' elements. As an example a button is transformed from this:

<button type="submit" data-bind="enable: isSearchEnabled,
                                 click: executeSearch">Go</button>

To this:

<div class="ui-btn ui-btn-inline ui-btn-corner-all ui-shadow ui-btn-up-c">
  <span class="ui-btn-inner ui-btn-corner-all">
    <span class="ui-btn-text">Go</span>
  </span>
  <input class="ui-btn-hidden" type="button" value="Go"
                  data-bind="enable: isSearchEnabled,
                                    click: executeSearch"/>
</div>

This causes all kinds of headaches when trying to use jQM with an MVVM or MVC framework.

In contrast, with Kendo when you create a button:

<a data-role="button"
   data-bind="click: executeSearch, { disabled: searchButtonDisabled }">Go</a>

It adds very little supporting structure:

<a data-role="button" class=" km-button"
      data-bind="click: executeSearch, { disabled: searchButtonDisabled }">
      <span class="km-text">Go</span>
</a>

And in many cases it leaves the DOM structure unaltered.

jQM has a more extensive set of styles

The jQuery Mobile framework is more extensive than Kendo. As a quick example, jQM nicely styles your list items:

jqm_list

With Kendo, you have to put in a bit of extra effort to style the list:

kendo_list

This is just one example of many - jQM is a big framework.

Kendo supports multiple mobile themes

The jQM UI is designed to look at home on iOS devices, which is just fine for the ~30% of people who own an iPhone. However, this UI just looks plain wrong on an Android or Windows Phone.

There are a few open source Android themes for jQM, but I didn't get a satisfactory result with any of them. Also, Microsoft have contributed a Metro theme to jQM, but it is rather ugly!

In contrast, Kendo supports iOS, Android, BlackBerry and Windows Phone, as shown on their online demo. This is pretty neat!

Kendo has a datasource concept

With the Knockout + jQM application I wrote a very simple TwitterSearchService which acts as a datasource. The Kendo framework has a DataSource component which makes integrating with services such as Twitter much easier, you typically provide configuration to the DataSource and it does the rest. Also, the UI components like the ListView integrate directly with the DataSource, with features like pull-to-load-more available out-of-the-box.

Knockout is open source, Kendo costs $$$

This one is pretty obvious really ...

Knockout is open source, and as a result doesn't cost you anything to use it. For an open source project it is very well documented and there are many blog posts that provide tutorials and solutions to problems. The interactive tutorial is a particularly fantastic idea.

Kendo will cost you a few hundred dollars to buy (http://www.kendoui.com/purchase.aspx). Considering that Kendo is a UI widget framework, MVVM framework and mobile framework, I would say that the price is very reasonable. Also, the documentation is of a similar quantity and quality to that of Knockout.

Conclusions

This article has been a mixed-bag of observations, thoughts and opinions and it is not intended to be an exhaustive comparison. Despite that, I hope it will be useful for others.

I certainly prefer the Knockout implementation of MVVM, I find it more powerful and flexible than the Kendo equivalent. However, Kendo's MVVM framework is certainly adequate.

When it comes to building mobile applications, the fully integrated Kendo solution has some pretty big advantages over Knockout and jQuery Mobile.

Regards, Colin E.