Backbone.js Tutorial - by noob for noobs
The official website describes Backbone.js as a library to supply structure to Javascript heavy web applications. After using Backbone.js for a week I could never see myself building any sort of Javascript functionality regardless of size without using Backbone.js or alternatives.
I have decided to write a quick introduction for those trying to grasp the mechanics behind it. I am only a beginner also and would love suggestions and tips to improve my code.
I am also very curious to hear what you think about how MVC ties into Javascript development and the most effective library you have used for logically organizing your Javascript.
Would be great to get a discussion on MVC vs MVVM vs others etc leave comments at the bottom!
Also could you implement this example better in another framework?
Understanding the Model View Controller Paradigm
I have used many frameworks which promote that they use MVC. I don't think I have ever seen the same fundamental principals implemented the same way.
Backbone.js has 4 classes: Models, Views, Controllers and Collections. The Models and Collections class work hand in hand and when combined essentially make up the M(model) of MVC.
The main concept I follow when using Backbone.js is to make Views listen for changes in the Model and react accordingly. I would recommend bookmarking the homepage documentation and I perusing the annotated source code.
Getting started
I am going to run you through a basic tutorial that should get you on the right path if you are a bit lost like I was when I started.
First of all we are going to just setup a basic page and include Backbone.js and Underscore.js(a dependency of Backbone.js)
<!DOCTYPE html> <html> <head> <title>I have a back bone</title> </head> <body> <button id="add-friend">Add Friend</button> <ul id="friends-list"> </ul> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script> <script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script> <script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js"></script> </body> </html>
For those of you who are lazy the full example can be viewed here and downloaded here
Setting up the main view
Each view has a HTML DOM element associated with it. You can read more about why here. Because this is our master view we are just going to associate the view with our page body in this example.
If the el(element) specified does not exist, Backbone.js will attempt to create it.
(function ($) { window.AppView = Backbone.View.extend({ el: $("body"), events: { "click #add-friend": "showPrompt", }, showPrompt: function () { var friend_name = prompt("Who is your friend?"); } }); var appview = new AppView; })(jQuery);
So we just wrapped our Backbone code with jQuery to make sure the page has loaded correctly. Then we create our main application view by extending Backbone and passing a JSON object with our options. We specified "body" to be the associated element for this view.
The events property is very powerful and lets us attach listeners to our views. In the example above we have attached a click listener to our button with id "add-friend". Read more about events here.
After we have setup our AppView, we can just call to initiate it at anytime.
Collecting the Models
A Model in Backbone.js can represent any entity you like and in this case we want it to represent a friend. We can easily create friend Models but without any structure they become fairly useless to us because we can't iterate through them unless they are grouped together. So Backbone.js implements the Collection class which allows us to order our models. Read more here.
Now we get to the fun part. You can bind listeners/events to Models and Collections. So whenever there are changes to the data we can call events to react accordingly.
We are going to add this code to our example which lets us add a friend Model to our friend Collection. We will then bind a listener to create a new list element when the data has changed.
(function ($) { Friend = Backbone.Model.extend({ //Create a model to hold friend atribute name: null }); Friends = Backbone.Collection.extend({ //This is our Friends collection and holds our Friend models initialize: function (models, options) { this.bind("add", options.view.addFriendLi); //Listen for new additions to the collection and call a view function if so } }); AppView = Backbone.View.extend({ el: $("body"), initialize: function () { this.friends = new Friends( null, { view: this }); //Create a friends collection when the view is initialized. //Pass it a reference to this view to create a connection between the two }, events: { "click #add-friend": "showPrompt", }, showPrompt: function () { var friend_name = prompt("Who is your friend?"); var friend_model = new Friend({ name: friend_name }); //Add a new friend model to our friend collection this.friends.add( friend_model ); }, addFriendLi: function (model) { //The parameter passed is a reference to the model that was added $("#friends-list").append("
Demo
Source
Conclusion
I hope this helps anyone trying to pick it up. I don't mind answering any questions that I have the ability to answer.
Would also love to hear to some optimization tips! p.s. Would love some insight into MVVM, MVC etc
Update: Changed the code to append the elements from the view and not the Model/Collection. The problem was described on ycombinator by emehrkay
Update 2: A user called svnlto had a pull request to fix up the example code to implement better coding practises, he was spot on so I merged his request into the master branch. You can view the pull request here.