Front-End

Backbone, The Primer: A Simple App

backbone

This is the fourth of four posts that guest author Greg MacWilliam has put together for Data Community DC: Backbone, The Primer. For more details about the API and an overview, please go back to the Introduction. For more on Models and Collections please review part two of this primer. A comprehensive look at Views and event bindings was in part three.

A simple REST application

Now its time to put it all together. Let's breakdown a complete RESTful application that performs all CRUD methods with our API.

1. The DOM

The first step in setting up any small application is to establish a simple interface for managing the tasks you intend to perform. Here, we've establish a "muppets-app" container element with a list (<ul>) for displaying all Muppet items, and a simple input form for defining new muppets.

Down below, a template is defined for rendering individual list items. Note that our list item template includes a "remove" button for clearing the item from the list.

Finally, we'll include our application's JavaScript as an external script. We can assume that all further example code will be included in muppet-app.js.

<div id="muppets-app"> <ul class="muppets-list"></ul> <div class="muppet-create"> <b>Add a Muppet</b> <fieldset> <label for="muppet-name">Name:</label> <input id="muppet-name" type="text"> </fieldset> <fieldset> <label for="muppet-job">Job:</label> <input id="muppet-job" type="text"> </fieldset> <button class="create">Create Muppet!</button> </div> </div> <script type="text/template" id="muppet-item-tmpl"> <p><a href="/muppets/<%= id %>"><%= name %></a></p> <p>Job: <i><%= occupation %></i></p> <button class="remove">x</button> </script> <script src="muppet-app.js"></script>

2. The Model and Collection

Now in "muppet-app.js", the first structures we'll define is the Model class for individual list items, and the Collection class for managing a list of models. The Collection class is configured with the URL of our API endpoint.

// Model class for each Muppet item var MuppetModel = Backbone.Model.extend({ defaults: { id: null, name: null, occupation: null } }); // Collection class for the Muppets list endpoint var MuppetCollection = Backbone.Collection.extend({ model: MuppetModel, url: '/muppets' });

3. A List Item View

The first View class that we'll want to define is for individual list items. This class will generate its own <li> container element, and will render itself with our list item template. That template function is being generated once, and then stored as a member of the class. All instances of this class will utilize that one parsed template function.

This view also configures an event for mapping clicks on the "remove" button to its model's destroy method (which will remove the model from its parent collection, and then dispatch a DELETE request from the model to the API).

// View class for displaying each muppet list item var MuppetsListItemView = Backbone.View.extend({ tagName: 'li', className: 'muppet', template: _.template($('#muppet-item-tmpl').html()), render: function() { var html = this.template(this.model.toJSON()); this.$el.html(html); return this; }, events: { 'click .remove': 'onRemove' }, onRemove: function() { this.model.destroy(); } });

4. A List View

Now we need a view class for rendering out lists of items, and capturing input from the "create" form.

This view binds a listener to its collection that will trigger the view to render whenever the collection finishes syncing with the API. That will force our view to re-render when initial data is loaded, or when items are created or destroyed.

This view renders a list item for each model in its collection. It first finds and empties its list container ("ul.muppets-list"), and then loops through its collection, building a new list item view for each model in the collection.

Lastly, this view configures an event that maps clicks on the "create" button to collecting form input, and creating a new collection item based on the input data.

// View class for rendering the list of all muppets var MuppetsListView = Backbone.View.extend({ el: '#muppets-app', initialize: function() { this.listenTo(this.collection, 'sync', this.render); }, render: function() { var $list = this.$('ul.muppets-list').empty(); this.collection.each(function(model) { var item = new MuppetsListItemView({model: model}); $list.append(item.render().$el); }, this); return this; }, events: { 'click .create': 'onCreate' }, onCreate: function() { var $name = this.$('#muppet-name'); var $job = this.$('#muppet-job'); if ($name.val()) { this.collection.create({ name: $name.val(), occupation: $job.val() }); $name.val(''); $job.val(''); } } });

5. Instantiation

Finally, we need to build instances of our components. We'll construct a collection instance to load data, and then construct a list view instance to display it. When our application components are all configured, all that's left to do is tell the collection to fetch for data!

// Create a new list collection, a list view, and then fetch list data: var muppetsList = new MuppetsCollection(); var muppetsView = new MuppetsListView({collection: muppetsList}); muppetsList.fetch();

Getting View Support

View management is by far the least regulated component of Backbone, and yet is –ironically– among the most uniquely disciplined roles in front-end engineering. While Backbone.View provides some very useful low-level utility features, it provides few high-level workflow features. As a result, major Backbone extenstions including Marionette and LayoutManager have become popular. Also see ContainerView for a minimalist extension of core Backbone.View features.

Thanks for reading. That's Backbone in a nutshell.

About the Author

Greg MacWilliam is an RIT alumni, currently working as a freelance web software engineer. He specializes in single-page application architecture and API design. He's worked for organizations including the National Park Service and NPR, and has taught JavaScript at the Art Institute of Washington. Greg has self-published several online games, and actively contributes to BackboneJS projects.

Greg's current side projects include the Backbone extensions EpoxyJS and ContainerView, as well as ConstellationJS for grid geometry operations.

You can follow him on Twitter and Github:

Backbone, The Primer

backbone

This is the first of four posts that guest author Greg MacWilliam has put together for Data Community DC: Backbone, The Primer.

Editors Note: Backbone.js is an MVC framework for front-end developers. It allows rapid development and prototyping of rich AJAX web applications in the same way that Django or Rails does for the backend. Part of the Data Science pipeline is reporting and visualization; and rich HTML reports that use Javascript libraries like D3 or Highcharts are already part of the Data Scientist's toolkit. As you'll see from this primer, leveraging Backbone will equip Data Scientists with the means to quickly deploy to the front-end without having to wade through many of the impediments that typically plague browser development.

A common sentiment I hear from developers coming to Backbone is that they don't know where to start with it. Unlike full-featured frameworks with prescribed workflows (ie: Angular or Ember), Backbone is a lightweight library with few opinions. At its worst, some would say that Backbone has TOO few opinions. At its best thought, Backbone is a flexible component library designed to provide a baseline solution for common application design patterns.

The core of Backbone provides a comprehensive RESTful service package. This primer assumes that you have a basic understanding of REST services, and will focus on the interactions of Backbone components with RESTful data services.

What's In The Box?

The first thing to familiarize with are the basic components provided by Backbone. There are three foundation components that make up Backbone applications:

  • Backbone.ModelModels store application data, and sync with REST services. A model may predefine its default attributes, and will emit events when any of its managed data attributes change.
  • Backbone.CollectionCollections manage a list of models, and sync with REST services. A collection provides basic search methods for querying its managed models, and emits events when the composition of its models change.
  • Backbone.ViewA view connects a model to its visual representation in the HTML Document Object Model (or, the "DOM"). Views render their associated model's data into the DOM, and capture user input from the DOM to send back into the model.
  • Bonus… Underscore!Backbone has two JavaScript library dependencies: jQuery and UnderscoreJS. Chances are good that you're familiar with jQuery. If you don't know Underscore, review its documentation. Underscore provides common functional programming for working with data structures. When setting up Backbone, you get the full capabilities of Underscore as part of the package!

While Backbone does include additional useful features, we'll be focusing on these core components in this primer.

Got REST Services?

For this primer, let's assume the following RESTful Muppets data service exists:

GET /muppets/

Gets a list of all Muppets within the application. Returns an array of all Muppet models (with some additional meta data):

{ "total": 2, "page": 1, "perPage": 10, "muppets": [ { "id": 1, "name": "Kermit", "occupation": "being green" }, { "id": 2, "name": "Gonzo", "occupation": "plumber" } ] }

POST /muppets/

Creates a new Muppet model based on the posted data. Returns the newly created model:

{ "id": 3, "name": "Animal", "occupation": "drummer" }

GET /muppets/:id

PUT /muppets/:id

DEL /muppets/:id

Gets, modifies, and/or deletes a specific user model. All actions return the requested/modified model:

{ "id": 1, "name": "Kermit", "occupation": "being green" }

What's Next?

In the next three posts, we'll discuss in more detail Models and Collections, Views, Event Binding, and walk through the creation of a simple app based on the REST API described above.

  • Part One: Introduction
  • Part Two: Models and Collections
  • Part Three: Views
  • Part Four: A Simple App

About the Author

Greg MacWilliam is an RIT alumni, currently working as a freelance web software engineer. He specializes in single-page application architecture and API design. He's worked for organizations including the National Park Service and NPR, and has taught JavaScript at the Art Institute of Washington. Greg has self-published several online games, and actively contributes to BackboneJS projects.

Greg's current side projects include the Backbone extensions EpoxyJS and ContainerView, as well as ConstellationJS for grid geometry operations.

You can follow him on Twitter and Github: