Saturday, June 8, 2013

Barebones Backbone.js

Backbone.JS Smallest steps

There are multiple tutorials out there for Backbone.js. Yet getting something working the way I wanted it seemed to be harder than it needed to be. Maybe it was me just getting ahead of myself but once the light bulb turned on in my head, I decided that it was time to document it in a blog.

The problem was simple, display certain information about an individual. However in order to do so, I wanted to separate Model and View code in separate files and also write a separate file that served as the glue code.
Most tutorials jump into collections etc and I just wanted to take it one step at a time i.e. populate a model object with some values and display it using a Handlebars template.

This post assumes you have some background about Backbone.js and Handlebars.

Project setup is as follows:
src/webapp/handlebars
  -- person.handlebars
src/webapp/js
   --person.js
   --person.model.js
   --person.views.js
   --app.js

src/webapp
  --index.html

person.handlebars

<table>
<tbody>
  <tr>
    <td nowrap> Person Name </td>
    <td nowrap> Person SSN</td>
  </tr>
  <tr>
      <td>{{ name }} </td>
      <td>{{ ssn }} </td>
  </tr>
</table> 


person.model.js


/*global _ Backbone Handlebars */
var Person = Person||{}; //create or use the 'Person' app namespace
Person.Models = (function () {

  var PersonModel = Backbone.Model.extend({
    defaults : {
      name : "default",
      ssn:"232432"
    }
  });

  //expose what we need
  return {PersonModel : PersonModel};

})();

person.views.js

/*global _ Backbone Handlebars */

var Person = Person|| {};

/**
 * Person Views
 */

Person.Views = (function() {
  var PersonView = Backbone.View.extend({
    el: $('body'), // attaches `this.el` to an existing element.

    //Called when the view is first created
    initialize : function() {
       _.bindAll(this, 'render'); // fixes loss of context for 'this' within methods
         this.render(); // not all views are self-rendering. This one is.
    },
    render : function() {
      
        $(this.el).append(Handlebars.templates.person(this.model.attributes));
        $(this.el).show();
        return this;
    }
  });
  return {PersonView : PersonView};
})();

person.js

/*global _ Backbone Handlebars */
var Person = Person||{}; //create or use the 'Person' app namespace
/**
 * USAGE : new Person.App()
 */
Person.App = (function() {
  var myPersonModel = new Person.Models.PersonModel({
      name : "Test Person",
      ssn : "214238890"
    });

  var myPersonView = new Person.Views.PersonView({
    model : myPersonModel
  });
  myPersonModel.fetch();

  //return a reference to the view
  return {AppView : myPersonView};
})();

app.js


/*global _ Backbone Handlebars Person window document */

/*
 * This is the glue code to wire up your app and perform initializations
 */
var Main = Main||{};

$(function() {


 var appView = new Person.App();
  //This should always be the last step in the startup.
  //See: http://backbonejs.org/#History
  Backbone.history.start();
});


index.html


<head>

  <script src="js/libs/modernizr-2.5.3-respond-1.1.0.min.js"></script>

</head>
<body>
  <div class = "container" id ="PersonView">
    <div class ="row-fluid">
      <h2>Person Information</h2>
    </div>
  </div>
 </body>
 <!-- Standard boilerplate scripts -->
  <script src="js/libs/jquery-1.8.2.min.js"></script>
  <script src="js/libs/bootstrap.min.js"></script>
  <script src="js/libs/underscore-1.4.3-min.js"></script>
  <script src="js/libs/backbone-0.9.9-min.js"></script>
  <script src="js/libs/handlebars.runtime-1.0.0.beta.6.js"></script>

  <!-- Application-specific -->
  <script src="js/person.model.js"></script>
  <script src="js/handlebars.templates.js"></script><!-- minified templates -->
  <script src="js/person.views.js"></script>
  <script src="js/person.js"></script>
  <script src="js/app.js"></script>


</html>

WRO4J

To create minified versions of JS and Templates, please configure WR04J plugin. Using this plugin, all Handlebars templates were minified into handlebars.templates.js