One of the challenges when building nontrivial Web applications is that JavaScript’s non-directive nature can initially lead to a lack of structure in your code, or in other words, a lack of… backbone. JavaScript is often written as a litany of free-hanging and unrelated blocks of code, and it doesn’t take long before it becomes hard to make sense of the logic and organization of your own code.
Backbone.js is a lightweight framework that addresses this issue by adding structure to JavaScript-heavy Web applications.
Self-contained building blocks
Backbone.js provides several classes (Model, Collection, View, Router) that you can extend to define the building blocks of your application. To build an app with Backbone.js, you first create the Models, Collections, and Views of your application. You then bring these components to life by defining a “Router” that provides the entry points of your application through a set of (deep-linkable) URLs.
With Backbone.js, your code is organized in self-contained entities (Models, Collections, Views): No more free-hanging and unrelated blocks of code.
Data Binding
With Backbone.js, you bind Views to Models so that when a Model’s data changes, all the Views bound to that Model automatically re-render. No more complex UI synchronization code.
Elegant REST Integration
Backbone.js also provides a natural / magical / elegant integration with RESTful services. If your back-end data is exposed through a pure RESTful API, retrieving (GET), creating (POST), updating (PUT), and deleting (DELETE) models is incredibly easy using the Backbone.js simple Model API.
Sample Application
In this three-part tutorial, you’ll create a Wine Cellar application. You can browse through a list of wines, as well as add, update, and delete wines.
- In Part 1 (this post), you define the basic infrastructure. You create a “read-only” version of the application: you’ll be able to retrieve a list of wine and get the details of each wine.
- In Part 2, you add the code to add, update and delete wines. You leverage Backbone’s powerful REST integration.
- In Part 3, you add complete support for history management and deep linking.
NOTE: I also blogged a non-Backbone version of the application here (Java back-end) and here (PHP back-end), which you can look at for comparison.
Part 1: The Read-Only Wine Cellar Application
You can run the application (Part 1) here.
Here is the code:
// Models window.Wine = Backbone.Model.extend(); window.WineCollection = Backbone.Collection.extend({ model:Wine, url:"../api/wines" }); // Views window.WineListView = Backbone.View.extend({ tagName:'ul', initialize:function () { this.model.bind("reset", this.render, this); }, render:function (eventName) { _.each(this.model.models, function (wine) { $(this.el).append(new WineListItemView({model:wine}).render().el); }, this); return this; } }); window.WineListItemView = Backbone.View.extend({ tagName:"li", template:_.template($('#tpl-wine-list-item').html()), render:function (eventName) { $(this.el).html(this.template(this.model.toJSON())); return this; } }); window.WineView = Backbone.View.extend({ template:_.template($('#tpl-wine-details').html()), render:function (eventName) { $(this.el).html(this.template(this.model.toJSON())); return this; } }); // Router var AppRouter = Backbone.Router.extend({ routes:{ "":"list", "wines/:id":"wineDetails" }, list:function () { this.wineList = new WineCollection(); this.wineListView = new WineListView({model:this.wineList}); this.wineList.fetch(); $('#sidebar').html(this.wineListView.render().el); }, wineDetails:function (id) { this.wine = this.wineList.get(id); this.wineView = new WineView({model:this.wine}); $('#content').html(this.wineView.render().el); } }); var app = new AppRouter(); Backbone.history.start();
Code Highlights:
- WineModel (line 2): Notice that we don’t need to explicitly define the attributes (name, country, year, etc). You could add validation, default values, etc. More on that in Part 2.
- WineCollection (lines 4 to 7): “model” indicates the nature of the collection. “url” provides the endpoint for the RESTFul API. This is all that’s needed to retrieve, create, update, and delete wines with Backbone’s simple Model API.
- WineListView (lines 10 to 25): The render() function iterates through the collection, instantiates a WineListItemView for each wine in the collection, and adds it to the wineList.
- WineListItemView (lines 27 to 38): The render() function merges the model data into the “wine-list-item” template (defined in index.html). By defining a separate View for list items, you will make it easy to update (re-render) a specific list item when the backing model changes without re-rendering the entire list. More on that in Part 2.
- WineView (lines 40 to 49): The view responsible for displaying the wine details in the Wine form. The render() function merges the model data (a specific wine) into the “wine-details” template retrieved from index.html.
- AppRouter (lines 52 to 71): Provides the entry points for the application through a set of (deep-linkable) URLs. Two routes are defined: The default route (“”) displays the list of wine. The “wines/:id” route displays the details of a specific wine in the wine form. Note that in Part 1, this route is not deep-linkable. You have to start the application with the default route and then select a specific wine. In Part 3, you will make sure you can deep-link to a specific wine.
Download
The source code for this application is hosted on GitHub here. And here is a quick link to the download.
You will need the RESTful services to run this application. A PHP version (using the Slim framework) is available as part of the download.
UPDATE (1/11/2012): A version of this application with a Java back-end (using JAX-RS and Jersey) is also available on GitHub here. You can find more information on the Java version of this application here.
Part 2 is available here.
Pingback: Backbone.js Wine Cellar Tutorial — Part 2: CRUD()
Pingback: Backbone.js Wine Cellar Tutorial — Part 1: Getting Started | Wine Bottle Covers()
Pingback: Backbone.js Wine Cellar Tutorial — Part 1: Getting Started « lolososo()
Pingback: Confluence: Mobile Devices Development()
Pingback: Backbone.js Wine Cellar Tutorial — Part 3: Deep Linking and Application States()
Pingback: Using Backbone.js with a RESTful Java Back-End()
Pingback: The LiveCycle Post | Using Backbone.js with a RESTful Java Back-End()
Pingback: Javascript Resources[updated] « Kooljoy.com Blog()
Pingback: Backbone.js Lessons Learned and Improved Sample App()
Pingback: Sample Application with Angular.JS()
Pingback: Sample Mobile App with Backbone.js and PhoneGap()
Pingback: Christophe Coenraets On Backbone.js And PhoneGap | Hire Flash Developers()
Pingback: Sample App with Backbone.js and Twitter Bootstrap()
Pingback: Good Tutorials | Wesley Duff()
Pingback: Robert McGhee » February 14th()
Pingback: Confluence: Front End Development Portal()
Pingback: A Spine.js with Handlebars.js JavaScript Tutorial | simple mind()
Pingback: Collection of Backbone.js tutorials | SpiderSoft Sydney developers()
Pingback: Links June 10, 2012 » Metodiev Research()
Pingback: jQuery Birthday Picker and others « William Jiang()
Pingback: Backbone 介绍及学习资料索引 | Hugo Web前端开发()
Pingback: Algunas notas sobre Backbone JS | Kinetica Solutions Blogs()
Pingback: Backbone.js and Twitter Bootstrap tutorials - Adriel Blog | Adriel Blog()
Pingback: Single-Page CRUD Application with Backbone.js and Twitter Bootstrap | Christophe Coenraets()
Pingback: Learn Backbone.js Completely | JavaScript is Sexy()
Pingback: Javascript Practice: Decided to include Node.js and MongoDB | thedev.ro by Alex Ionica()
Pingback: Anonymous()
Pingback: Part 6: Displaying Wildfires | blog.davebouwman.com()
Pingback: Baby steps to Backbone.js: Exploring collections | Tu Ngoc Man()
Pingback: How can I get Tweet Timeline with using Backbone.js? - How-To Video()
Pingback: Sample App with Backbone.js and Twitter Bootstrap | HTML CSS3()
Pingback: Backbone Example Sites with Tutorials | Hugo Mineiro Portfolio()
Pingback: Where to Learn backbone.js online | Learn Web Tutorials()
Pingback: Backbone, Django and Tastypie – view item is not populating view list | Technology & Programming Answers()
Pingback: Week 0, Day 3 | Leaena.com()
Pingback: Render function of view is not working | Technology & Programming()
Pingback: Getting started with Backbone.js | Anders Grendstadbakk()
Pingback: In One Post: Backbone.js | Day of the Duck()
Pingback: How to hoop a demonstrate router slight outcome in BackBone.js controlling ajax - Abram()
Pingback: backbone.js | mauroprogram's Blog()
Pingback: Материалы для изучения backbone.js « Blog — organiser()
Pingback: » Libraries - @ fake's()
Pingback: Superonline Web Hosting | Great at WebHosting()
Pingback: Web Hosting Fiyatlar | Great Value Webhosting()
Pingback: Superonline Web Hosting | Tip Top Webhosting()
Pingback: Backbone Internet Web Hosting | Tip Top Webhosting()
Pingback: Web Hosting Fiyat | Great Value Webhosting()
Pingback: Stylish Backbone Wine Cellar | Wine Cellar Storages()
Pingback: Abordagens da Decomposição de Software()
Pingback: 2019 JAMB Runs/Runz 2019 JAMB Expo 2019/2020 JAMB CBT Expo / Runs / runz / answers / sites – 2019 JAMB Runs 2019 JAMB Expo 2019/2020 jamb CBT Runs Expo answer()
Pingback: Jamb Runs 2019 | 2019/2020 JAMB CBT Expo Runs Runz Answers Sites – 2019 JAMB Runs 2019 JAMB Expo 2019/2020 jamb CBT Runs Expo answer()
Pingback: 2019 JAMB EXPO/RUNZ | JAMB RUNS 2019 – Jamb Expo runs()
Pingback: Latest exam blog – love god blog()
Pingback: Latest news on exam – examblog()
Pingback: Latest JAMB exam runs – JAMB Expo runs()
Pingback: JAMB Expo Runs – JAMB Runs Expo()
Pingback: Exam Expo runs – examsitevlog()
Pingback: In executive order, Trump to dramatically change US | Noisemakers()