- The first thing you need to know about Backbone.js is that it’s friendly. It is not difficult to learn or use, and the time you will spend to learn this serviceable framework will be worth it. You will learn how to use one of the most popular front-end frameworks and how to develop modern web applications on the front end. Backbone.js has thorough documentation and the most active community of all the front-end JavaScript frameworks. Once you start making your own website, you will find yourself making frequent stops to the Backbone.js documentation. I should note that Angular.js and Ember.js are robust and feature-rich front-end frameworks that provide more than Backbone.js, and they permit you to develop applications with lesser code than Backbone.js. Nevertheless, I still think developers should learn Backbone.js first, particularly as it is easier to learn and offers you with a solid understanding of what a JavaScript framework is and how a JavaScript framework functions.
- The second thing you need to know is that if you run a market survey you will know that Backbone developers are in high demand these days.
Backbone.js adds structure to client-side applications in order to avoid spaghetti-code mess. Backbone is an unbelievably small library for the amount of functionality and structure it offers you. It depends on two other java script libraries underscore.js and jquery.
Fast Facts
- Its core components include Model, View, Collection, Router.
- It has event-driven communication between Views and Models. In other words it provides developers fine control over what changes in view by adding event listeners to any attribute in a model.
- It supports data bindings via manual events or a separate Key-value observing (KVO) library.
- It supports flexible out of the box interfaces so models can be simply tied to a backend.
- It provides clear and flexible conventions for structuring applications.
Getting set up
In this article we will mainly focus on one of the core components of backbone.js i.e. Model. In the upcoming articles however we will one by one look into all the other elements of backbone.js. I am assuming that the reader has basic knowledge of java programming as my prime focus will be to explain how to use backbone for our applications. I will be using JSBIN for running my code.For startup let’s first define some boilerplate markup you can use to specify the dependencies Backbone requires.
You can write this code in text editor of your choice, run the code and then replace the line between the script tags with any other JavaScript code of yours.
Model
Models are the heart of any JavaScript application where you keep your interactive data as well as the logic around the data. These special JavaScript objects are created from backbone’s built-in model, optionally extended by you to add functionality. Model offers a basic set of functionality for handling changes. Models can be created by extending backbone.model as follows.
Have a look at the code and see what different commands are doing.
<!DOCTYPE HTML> <html> <head> <script src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.14/require.js"></script> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script src="http://documentcloud.github.com/underscore/underscore-min.js"></script> <script src="http://documentcloud.github.com/backbone/backbone-min.js"></script> <script> var jedi = Backbone.Model.extend({}); var jedi1 = new jedi(); console.log(JSON.stringify(jedi1)); var jedi2 = new jedi({ title: 'Check the attributes of both model instances in the console.', completed: true }); console.log(JSON.stringify(jedi2)); </script> </body> </html>
The above code can also be found in the JSBIN link.
Initialization
The initialize() method is called when a new instance of a model is created. It is not necessary to use it but however it is considered to be a good practice.
<script> var jedi = Backbone.Model.extend({ initialize: function() { console.log('This model has been initialized.'); } }); var myjedi = new jedi(); </script>
The demo can be found in the JSBIN link and the output of the code is as following screenshot.
Getting a Model
Model.get() provides an easy access to a model’s attributes. The following code shows the use of get method.
<script> var jedi = Backbone.Model.extend({ // Default jedi attribute values defaults: { title: '', completed: false } }); var jedi1 = new jedi(); console.log(jedi1.get('title')); // empty string console.log(jedi1.get('completed')); // false var jedi2 = new jedi({ title: "Retrieved with model's get() method.", completed: true }); console.log(jedi2.get('title')); console.log(jedi2.get('completed')); // true </script>
The demo code can be found in the JSBIN link and output of the code is as following screenshot.
Setting the Model
Sometimes you will want your model to contain default values. This can easily be done by setting a property name ‘defaults’ in your model declaration. Model.set() will set a hash containing one or more attributes in your model. When there is a change in any of these attributes, the state of the model alters and a “change” event is triggered on it. Change events for each attribute are also triggered and can be bound. I will explain this concept further with an example.
<script> var jedi = Backbone.Model.extend({ // Default jedi attribute values defaults: { title: '', completed: false } }); var myjedi = new jedi({ title: "Set through instantiation." }); console.log('jedi title: ' + myjedi.get('title')); console.log('Completed: ' + myjedi.get('completed')); myjedi.set("title", "Title attribute set through Model.set()."); console.log('jedi title: ' + myjedi.get('title')); console.log('Completed: ' + myjedi.get('completed')); myjedi.set({ title: "Both attributes set through Model.set().", completed: true }); console.log('jedi title: ' + myjedi.get('title')); console.log('Completed: ' + myjedi.get('completed')); </script>
The following screenshot shows the output of the previous code. The demo code can be found in the embedded JSBIN link.
Direct Access
Models expose an .attributes attribute that represents an internal hash containing the state of that model. Generally it is in the form of a JSON object similar to the model data you might find on the server but can take other forms. Setting values through the .attributes attribute on a model bypasses triggers bound to the model. The code for the example is as follows.
<script> var Person = new Backbone.Model(); Person.on("change:name", function() { console.log('Name changed'); }); Person.set({ name: 'Andrew' }); // log entry: Name changed Person.set({ name: 'Jeremy' }, { silent: true }); // no log entry console.log(Person.hasChanged("name")); // true: change was recorded console.log(Person.hasChanged(null)); // true: something (anything) has changed </script>
The output of the previous code can be found in the following screen shot. The code can be found in the JSBIN link.
Listening for changes to your model
Now we come to one of the more useful part of backbone. All the attributes of a model can have listeners bound to them in order to detect changes to their values. In our initialize function we are going to bind a function call every time we change the value of our attribute. If you want to get a notification when a Backbone model changes you can bind a listener to the model for its change event. A convenient place to add listeners is in the initialize() function as shown below:
<script> var Todo = Backbone.Model.extend({ // Default todo attribute values defaults: { title: '', completed: false }, initialize: function() { console.log('This model has been initialized.'); this.on('change', function() { console.log('- Values for this model have changed.'); }); } }); var myTodo = new Todo(); myTodo.set('title', 'The listener is triggered whenever an attribute value changes.'); console.log('Title has changed: ' + myTodo.get('title')); myTodo.set('completed', true); console.log('Completed has changed: ' + myTodo.get('completed')); myTodo.set({ title: 'Changing more than one attribute at the same time only triggers the listener once.', completed: true }); </script>
The output of the previous code can be found in the following screenshot and the demo code can be found in JSBIN link.
Validation
Backbone supports model validation through model.validate(), which permits checking the attribute values for a model prior to setting or saving them. By default, validation occurs when the model is persisted using the save() method or when set() is called if {validate:true} is passed as an argument.
<script> var Person = new Backbone.Model({ name: 'Joseph' }); // Validate the model name Person.validate = function(attrs) { if (!attrs.name) { return 'I need your name'; } }; // Change the name Person.set({ name: 'Sara' }); console.log(Person.get('name')); // 'Sara' // Remove the name attribute, force validation Person.unset('name', { validate: true }); // false </script>
Now when we will run the code in our console we will see it display “Sara” as can be seen in the image below. The demo code can be found in JSBIN link.