Many developers use jQuery to build web applications – however as the project grows – the application turns into a nested piles of jQuery selectors and callbacks. This makes the development process more complex, and the code becomes more cluttered and hard to understand. If you have already faced this problem? or just started with JavaScript frameworks and are confused between Backbone or Knockout. Then you are at the right place because this is your basic guide on understanding JavaScript frameworks that is mainly focused on Backbone vs Knockout. Before reading this tutorial you might love to see our previous posts on JavaScript: Top Seven JavaScript Resources for Developers and The Most Interesting HTML/JS/DOM and CSS hacks. Enjoy!
Wondering about the solution?
You can use the client-side JS frameworks for building web apps. These frameworks provide help in structuring an application. In this post we will discuss about two of the most popular client-side JS frameworks: Backbone.js and Knockout.js. We’ll have a basic understanding of both these JavaScript frameworks and which one you should choose for your web application development project.
An Overview of Backbone.js
Backbone.js enforces that event-driven communication takes place between views and models, so as to make the code less cluttered. Backbone.js helps organize the code into modular pattern, which is also referred to as MVC pattern that separates the code in:
- Model Layer
- View Layer
- Controller Layer
An Overview of Knockout.js
Knockout.js is one of the most sought-after JavaScript library whose popularity is growing with each passing day. This library helps in building responsive and interactive web apps. It uses two-way data bindings: when a UI field is updated the content gets updated by the underlying model variable and vice versa.
Real Time Comparison – Application in Backbone & Knockout
Now let us take a basic example application to demonstrate how a few common features can be implemented in Backbone and Knockout. For instance, let’s consider an example application that mocks a file sharing app of a client, which:
- enables you to add files to the list of the files that are located on a (mocked) server,
- and delete files from the list.
Basic Application Structure
- Backbone
A basic application created using Backbone comprises of a view, a model and a collection. Let us now discuss about an example that consists of all these three elements. However, to make it more interesting we will also use a Backbone.Marionette.CompositeView (i.e. GridView) extension rather than using a Backbone.View only. The models will be utilized and provided by Backbone.Model and collections by Backbone.Collection.
var fileCollection = new Backbone.Collection();
var gridView = new GridView({
collection: fileCollection
});
gridView.render();
$('#grid').html(gridView.el);
In the above example, as you can see we’re creating an instance of Backbone.Collection. And because the GridView is instantiated with the variable fileCollection, it will auto-update the view at the time when the model or collection is changed. Lastly, we’re appending the GridView’s element to the document object model (DOM).
- Knockout.js
Unlike Backbone in Knockout we’ve only a single view model, which may contain sub-models. In case of our example app, we’ll call our main view model as “App” and instantiate. In addition, we’ll begin working on it when the DOM has been built. We’ll be including the following script in our HTML:
<script>
// create and start the app
var app = new App();
app.start();
ko.applyBindings(app);
</script>
The sub-models, files collection and sequence of the uploaded files will be instantiated by the app class.
function App() {
this.files = new FileCollection();
this.queues = ko.observableArray();
}
App.prototype.start = function() {
// load data
};
function FileCollection() {
// items will be instances of FileModel
this.items = ko.observableArray();
}
function FileModel(name) {
this.name = ko.observable(name || '');
}
The above code exhibits that we can either make use of our own FileCollection class or merely use a ko.observableArray. Besides, the latter boasts a similar interface just like any standard JavaScript array, however it listens to changes done on the array and accordingly updates the user interface.
Retrieving data from a REST service
Let’s us consider that we contain a REST service, which lists the current files that are saved on the server. And the files are listed by the service in the JSON structure as follows:
[{ "name": "tarzan-of-the-apes.pdf" },]
- Backbone
The models and collections in Backbone framework includes a built-in implementation of the REST services.
var FileCollection = Backbone.Collection.extend({
url: 'files.json'
});
var fileCollection = new FileCollection();
fileCollection.fetch();
When we call the fetch() function on the fileCollection, a GET request to files.json is made. In addition, it will populate the collection. What’s more? Every entry will act as an instance of Backbone.Model. In order to fetch through the hash options, you can pass success as well as error callbacks. Additionally, you can even subscribe to the “sync event on the collection”. This is action will be triggered whenever the collection will sync with the server successfully.
fileCollection.on('sync', function (collection) {
console.log(‘Collection updated from server’, collection);
});
- Knockout.js
Knockout do not include AJAX facilities of its own. This can be accomplished via a library such as jQuery or Zepto.js (in fact, you can even choose a simple JavaScript to perform the same if you’re interested). Also, you cannot get access to ways to populate the model along with the AJAX loaded data via Knockout core. However, there is a plugin that can get the job done, but we’ll usually do it manually. In case every variable in your model is an observable, it will most likely result in producing a certain amount of code. The sample code as shown below uses jQuery’s ajax function and calls upon the FileCollection load method, resulting in creation of new array entries.
App.prototype.start = function() {
var self = this;
$.ajax({
url: 'files.json'
}).done(function(data) {
self.files.load(data);
});
};
FileCollection.prototype.load = function(data) {
// remove old items (using the “splice” method to keep the current observableArray)
this.items.splice(0, this.items().length);
// add new items
for (var i = 0, len = data.length; i < len; i++) {
this.items.push(new FileModel(data[i].name));
}
};
Deleting items
- Backbone
A destroy method is provided by Backbone.Model. On calling this method a DELETE request is triggered to the REST API automatically. This will get rid of the item in question. In order to trigger the request two conditions need to be completed: we’ll have to define the model urlRoot property, and it is compulsory for the item to have an “id” attribute. Just like the sync and fetch events, an option hash can be passed on to the destroy method. This will provide custom callbacks or else a relative URL will be provided for the DELETE request in case of our example, as follows.
this.model.destroy({
url: '/api/files',
emulateJSON: true,
data: { path: this.model.get('name') },
complete: function () {
//trigger events here, the DELETE request is complete
}
});
Not to mention, a user action will trigger the deletion of the items. In the following code, you can see that a GridView is set up, which will help in handling the “click events” on a DOM element.
<a class="js_remove_file" href="javascript:void(0);">Remove</a>
var GridRow = Backbone.Marionette.ItemView.extend({
events: {
'click .js_remove_file': 'trash'
},
trash: function () {
this.model.destroy({ /* see above… */ });
}
});
- Knockout.js
In order to delete items from an array in a Knockout application, we’ll have to learn about item index – that we want to delete. This can be accomplished with help of Knockout built-in variable (i.e. an observable), in our case. This is relevant when added in a foreach binding – $index. Let’s us assume the delete link alongside to the item in a table cell as follows: Delete file The above line of code will bind a click handler to FileCollection remove method. This method helps in deleting an item present at a specific index:
FileCollection.prototype.remove = function(index) {
var self = this;
return function() {
self.items()[index].remove();
self.items.splice(index, 1);
};
};
The remove method on the FileModel is called by the event handler. And then, the item in question is deleted from the array. A remove method is added on the FileModel, in order to carry out cleanup work of some additional per-item. For instance, notifying the REST service about deletion of an item. This is because Knockout framework isn’t aware about any REST services, and the task needs to be performed manually:
FileModel.prototype.remove = function() {
// notify the server of the file deletion; something like
$.ajax({
url: 'files.json',
type: 'DELETE',
data: { path: this.name() }
})
};
Wrapping Up!
Backbone comes loaded with built-in functionality that helps to accelerate web development, including REST support, jQuery-like event binding etc. Backbone also helps teams of developers maintain a clean code base.
Also, the Backbone framework help developers to keep a clean app code base, as it helps in determining the structure of the application. The downside to using Backbone is that it has a steep learning curve and is difficult to understand. And so, using it for creating a small app can make your less flexible. In simple words, Backbone is an ideal framework for creating large-size application.
Knockout is fairly easy to understand and can be set up in a simplified manner, allowing to develop an app quickly. It boasts a two-way data binding mechanism that helps to synchronize your model with the UI. Also, it helps in making the code clean, as it provides a separation of the view and the business logic. However, Knockout isn’t the best choice when it comes to structuring the application, as it emphasizes on data binding only.
Author Bio – Being a well-known blogger from Designs2html Ltd. Sarah Parker gives important and best tips on converting PSD to WordPress theme and various other web design aspects. Additionally, she is devotee of offering his creative thoughts identified with web outline
Akshay Joshi says
Thank you John for your valuable comment.