Model and View in Backbone.js

Model and View are the integral part of Backbone.js. These are used to keep the data and the business logic separate from the user interface.

Model is an atomic unit responsible to handle all business data and computations related to these data. It should not involve in any UI related activities.

View is an atomic unit responsible for creating and maintaining the user interface. It keeps track of the model and updates the view on model update. The view should not be involved in direct manipulation of the model data.


Sample Example

We will create a simple application using backbone.js to understand model and view. The application will allow us to create our profile, once created it shows us our profile. Shown below is our 'My Profile' application:

My Profile

Create Profile
Name Email Id
Mobile Hometown
Create

Creating the Model

Our model will hold all the data that we enter in the UI i.e. name, email id, mobile number and hometown. Additionally it also creates a profile ID (pid) for the profile. Backbone.Model also offers the ability to validate the model data; we will utilize it to validate the data entered by the user.

The code below shows the Profile model.

var Profile = Backbone.Model.extend({
         
     defaults : {
         pid: "",
         name:"",
         email:"",
         mobile:"",
         hometown:""
     },
 
     initialize : function(){
         this.set({'pid': Math.floor(Math.random() * 1000) + 9999});
 
         if (!this.isValid()) {
              alert(this.validationError);
         }
     },
 
     validate: function(attrs, options){
         if(attrs.name.length == 0)
             return "Name cannot be empty";
         if(attrs.email.length == 0)
             return "Email Id cannot be empty";
         if(attrs.mobile.length == 0)
             return "Mobile cannot be empty";
         if(attrs.hometown.length == 0)
             return "Hometown cannot be empty";
     },
 
     getJSONRepresentation: function(){
         return this.toJSON();
     }    
 });

Here are some points that will simplify our understanding of the above code:

  • To create our model we should extend Backbone.Model, to create out Profile model we did the same.
  • defaults is used to set the default value for the model attributes, we have set an empty string as the default value for all our attributes.
  • initialize is used to perform any operation on creation of an object, we had assigned the profile ID (pid) value once the model object is initialized. We also check for errors during initializations.
  • validate is used to validate our model data, we have used it to check if the user has entered non empty strings.
  • set is used to set any attribute value of the model, similarly we can use get (e.g. - get('name')) to get the attribute value.
  • validationError returns the error messages that are set in the validate method.
  • isValid checks of the model attributes have valid data, internally it runs validate to check if any validation failed.
  • toJSON returns the model attributes in a JSON format.

Creating the View

Our View will render the user interface and handle all user interaction with the interface. Shown below is the ProfileView used in our application.

var ProfileView = Backbone.View.extend({
         
     el: $("body"),
 
     template: _.template($("#view-profile").html()),
     
     events: {
         "click #createProfile" : "createProfile",
         "click #create" : "showCreateDiv"
     },
 
     initialize: function() {
         this.listenTo(this.model, "change", this.render);
     },
 
     render: function(){
         $("#contact-list").append("<div>"+this.model.get('name')+"</div>");
     },
 
     createProfile : function(){
         this.model =  new Profile({
             'name':$("#name").val(),
             'email':$("#email").val(),
             'mobile':$("#mobile").val(),
             'hometown':$("#hometown").val()});
         if(this.model.isValid()){
             this.showProfile();
         }
     },
 
     showProfile: function(){
         $("#create-profile").hide();
         $(".profile").append(this.template(this.model.getJSONRepresentation()));
     },
 
     showCreateDiv: function(){
         $("#create").hide();
         $("#create-profile").show();
     }
 });

Here are some points that will simplify our understanding of our view:

  • To create a view we need to extend Backbone.View
  • Every Backbone View is associated with a DOM element that the view will work. This association is done via the el property. In our case we have associated it with the body.
  • We can bind any DOM element to an event using the events method; we have bound the click events with two different elements and specified the methods that should be called once the click is dispatched.
  • We can use templates to render our view, the template function is used for this purpose. We are using underscore template (from underscore.js) to render our view.
  • As with the model, view also provides the initialize method to perform any task on initialization.
  • All view rendering should be done in the render function; we should override the Backbone.View’s render function in our views. This function updates el with the new updated html.

The HTML Page

Shown below is the HTML of our application.

We can see that the view is initialized with a null model in the HTML, it is updated with a new model when the user creates a profile. Also notice the template we have used, which is in bold in the code below.

<!DOCTYPE HTML>
 <html>
 <head>
     <title>Backbone js Intro</title>
     <script type="text/javascript" src="js/json2.js"></script>
     <script type="text/javascript" src="js/jquery.min.js"></script>
     <script type="text/javascript" src="js/underscore.js"></script>
     <script type="text/javascript" src="js/backbone-min.js"></script>
     <script type="text/javascript" src="js/model_view.js"></script> <!-- Contains the  model and view -->
     <style type="text/css">
         .profile{display: inline-block;}
         #edit, #create-profile, #view-profile{display: none;}
     </style>
<script type="text/javascript">
var view=null;
$(document).ready(function(){
view = new ProfileView({model:null});
});
</script> </head> <body> <div id="container"> <h2>My Profile</h2> <div> <a href="#" id="create">Create Profile</a> <a href="#" id="edit">Edit Profile</a> </div> <div id="create-profile" class="profile"> <fieldset> <legend style="font-size:20px">Create Profile</legend> <table> <tr> <td>Name</td> <td><input type="text" name="name" id="name"></td> <td>Email Id</td> <td><input type="text" name="email" id="email"></td> </tr> <tr> <td>Mobile</td> <td><input type="text" name="mobile" id="mobile"></td> <td>Hometown</td> <td><input type="text" name="hometown" id="hometown"></td> </tr> <tr> <td align="left"><a href="#" id="createProfile">Create</a></td> </tr> </table> </fieldset> </div> <br> <div class="profile"> <script type="text/template" id="view-profile"> <fieldset> <legend style="font-size:14px">Profile: <%- pid %></legend> <table id="profileTable"> <tr> <td>Name</td> <td><%- name %></td> <td>Email Id</td> <td><%- email %></td> </tr> <tr> <td>Mobile</td> <td><%- mobile %></td> <td>Hometown</td> <td><%- hometown %></td> </tr> </table> </fieldset> </script> </div> </div> </body> </html>
RELATED ARTICLES

Introducing Backbone Collection

Backbone Collections are set of related models. This is used in situations where we are handling a set of related models.

View Article

A Glance at Backbone.js

Backbone.js is a JavaScript framework that attempts to structure a web application by separating the domain data & business logic from the user interface.

View Article