CHAPTER 4

image

Backbone View and Templating Libraries

The previous chapter focused on the classes and functionality that Backbone provides to power the model layer of your web application. Now the focus shifts to the view layer, with Backbone.View being the main class behind it all. We’ll also look at how templating libraries work to make updating your HTML pages a whole lot easier. As well as looking at Underscore, we’ll spend some time looking at Handlebars and Mustache, two leading template libraries for JavaScript applications.

Code Setup

To execute the code in theexamples, we will continue to use index.html from the previous chapter. Becausewe will be using the models and collections previously defined, any JavaScript code snippets for the view should be placed after their definition and instantiation, as follows:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>My App</title>
</head>
<body>
<scriptsrc="js/external/jquery-1.10.2.js"></script>
<scriptsrc="js/external/underscore.js"></script>
<scriptsrc="js/external/backbone.js"></script>

<script>
       Book = Backbone.Model.extend({
         //all the Book model definition source from Chapter 3.
       });
        
       /**
        * Define a collection based on book
        **/
       var Library = Backbone.Collection.extend({model: Book,
       //all the Library collection definition from Chapter 3.
        });
        
       //instantiate books
       varbookOne = new Book({name: 'Beginning Backbone', author: 'James Sugrue', year: 2013});
       varbookTwo = new Book({name: 'Pro Javascript Design Patterns', author:'Dustin Diaz, Ross Harmes', year: 2012});
        
       //create library
       varmyLibrary = new Library([bookOne, bookTwo]);
        
       //Here is where all your Backbone view code will appear
</script>
</body>
</html>

Backbone Views

When speaking of Backbone.View, we are referring to the JavaScript objects that are created in a Backbone application to organize the code into logical views. This means that although a view can update the HTML that is present in a view, usually with a templating library, the view will listen for changes in the model and render the changes on a designated section of your HTML page.

Creating a Backbone View

Creating your own view definition is done through the Backbone.View.extend() function. Just as with Backbone.Model and Backbone.Collection, you can pass an I nitialize function that will get invoked on construction of a new instance.

//Define the Library View
LibraryView = Backbone.View.extend({
        
       initialize: function(){
              console.log('View created'),
       },
        
});

To create a new instance of your view, simply use the new operator.

//Create an instance of the view
varmyView = new LibraryView();

You can pass additional options when creating the view, such as the model that the view is being attached to and the element that the view should be attached to. In the following code snippet, an instance of a Book model is passed through to the LibaryView, which can be accessed in the initialize function of the view:

varthisBook = new Book({name : 'Beginning Backbone',
                                             author: 'James Sugrue'});//Create an instance of the view
varmyView = new LibraryView({model: thisBook});

We’ll see how other attributes such as collection, el, id, className, tagName, and attributes can be passed through on construction of the view later in this chapter.

Binding to the Physical View

To bind your View classto an HTML page, you will need to utilize the el attribute, which is at the center of any view. el is the reference to the DOM element on your HTML page that is associated with the view.

The DOM element is available at all times, whether the view has been rendered or not. Because of this, the entire view can be created before it is rendered, at which point the element is inserted into the DOM at once, with as few repaints as possible.

There are two ways to use el: by referencing an existing DOM element or by creating a new one.

By passing an el attribute to the constructor, you are telling the view which DOM element itshould attach to. For example, if the HTML page had a div created to contain the library view contents, you would want to pass a reference to that element when constructing the view.

<body>
<div id="myLibraryViewSection"></div>

The reference is made using standard CSS selectors that use #<element_id> or .<element_class>.

//Create an instance of the view with a model and an element
varmyView = new LibraryView({
model: thisBook,
el: '#myLibraryViewSection'
});

You can also create the el for the view dynamically by passing a number of properties to the view when constructing it.

  • tagName: The name of the HTML element to use for the view. If none is specified, the value of tagNamewill default to div.
  • className: The CSS class that will be used to render this element. This property is optional. You can specify a number of classes for the element, passing them through as space-separated values.
  • id: The ID to assign to the element. This property is optional.
  • attributes: Additional attributes to assign to the element, such as data- attributes in name-value pairs.
//Create a view that will build its own DOM element
varmyNewView = new LibraryView({model: thisBook,
 tagName: 'ul',
 className: 'libraryview',
 id: 'library',
 attributes: {'data-date': new Date()}
});
console.log(myNewView.el);

The result of myNewView.el will now be as follows:

<ul id='library' class='libraryview' data-date='Mon Aug 05 2013 13:54:20 GMT+0100 (IST)'></ul>

If none of these properties is passed through, the el is created as an empty div element.

All of the properties are accessible through the view’s object, regardless of whether the el was newly created or passed through as a reference.

image Note  When constructing the el for the view, it will not be appended to the DOM automatically.

Rendering Content

To get your view content onto a page, you will need to override the render function. Left unimplemented, the content of the view will never be rendered.

To have the view render automatically on construction, you could call the render function from the view’s initialize function.

//Define the Library View
LibraryView = Backbone.View.extend({
        
initialize: function(){
                this.render();
        },
        render: function(){
        this.$el.html('Hello Library'),
        return this;
 }
  
});

Of course, a more useful render function would make use of the model or collection that is present in the view.

render: function(){
this.$el.html('Book Name: ' + this.model.get('name'));
return this;
}

Note how the render function has a return this statement at the end. This is a convention that is encouraged by Backbone to allow chained calls. With the function returning a reference to the view, you can do further operations that require that reference. This can be particularly useful when you are dealing with nested views, providing access to the  el property of the subview. The following code shows how you could append all of the subviews onto the parent view, thanks to the easy access to the el property:

render: function(){
        for (vari = 0; i<this.subviews.length; i++){
                this.$el.append(this.subviews[i].render().el);
        }
        return this;
}

As you can see from the previous snippets, because you have access to the $el property, HTML can be set directly on the element. However, this approach is prone to errorand leads to a lot of messy HTML code within your JavaScript source. It is preferable to use one of the many templating libraries to provide a cleaner, more efficient rendering implementation. We’ll look at the templating options available later in this chapter.

Note that rather than using a single model in our rendering, we could also pass a collection to the view when creating a new instance.

varmyLibraryView = new LibraryView({
                                        collection: myLibrary,
                                        el: '#myLibraryViewSection'
       });

The render method could now deal with the entire collection of models.

render: function(){
              
                for(vari =0; i<this.collection.size(); i++){
                        this.$el.append('<li>Book Name: ' + this.collection.at(i).get('name') + '</li>'),
                }
        return this;
   }

It can be a good idea to give each element that you render a unique ID so that it can be easily found at a later stage, should you want to manipulate or hide it. In this case, we could consider the name as the unique identifier and tag each <li> as follows:

render: function(){
              
                for(vari =0; i<this.collection.size(); i++){
                        varbookname = this.collection.at(i).get('name'),
                        this.$el.append('<li id='' + bookname + ''>Book Name: ' + bookname) + '</li>'),
                }
        return this;
   }

Whether you need to use a model or a collection will vary depending on your view requirements.

Finally, it is possible to remove the view entirely from the DOM. This will also result in all event listeners being disposed of.

myLibraryView.remove();

Finding Elements Within the View

It is common to need to find nested elements within your view and run other jQuery functions within the view’sscope. Backbone provides an additional $el property that functions as a shorthand for $(view.el).

For example, to find a subelement within your view, you can use the following code. This will find the element with the ID Beginning Backbone if it exists within the view. Recall that in the previous sections we assigned unique identifiers to each of the <li> tags in the view.

$el.find('#Beginning Backbone'),

Similarly, Backbone provides a $(<selector>) function as shorthand for $(view.el).find(<selector>), making any code that deals with subelements more elegant and readable.

$('#Beginning Backbone'),

Both snippets of the previous code achieve the same result: finding an element with the ID of myelement within the scope of the current view.

Changing DOM Element

There may be situations in which you want to switch the DOM element that the view is applied to during the application lifecycle. This can be achieved with the .setElement() function, which takes a reference to the new element to be used. The following code assumes you have a div created in your HTML with anID of anotherViewSection:

myView.setElement('#anotherViewSection'),

This function will also create a new version of the $el reference and ensure that any events that were registered under the old element get transferred to the new one.

View Events

Now that the view is rendering, you will probably want to add some events to make it interactive. Once again, this is made simple in Backbone with the ability to specify a hash of events in the view definition.

The events listed in the hash will use jQuery’son function to provide callbacks for DOM events with the view. The format {'event selector': 'callback'} is used to define the events that will be handled. The following example shows how to add a click listener to elements with the ID of book:

//Define the Library View
LibraryView = Backbone.View.extend({
       events: {
               'click #book' : 'alertBook'
       },
       render: function(){
              
               for(vari =0; i<this.collection.size(); i++){
                      this.$el.append('<li id="book">Book Name: ' + this.collection.at(i).get('name') + '</li>'),
               }
                      
       return this;
   },

   alertBook: function(e){
       alert('Book clicked'),
   }
                        
});

If no selector is defined, the event will be bound to this.el, the root element of the view.

For example, to add a click handler to the entire view, you could simply use this:

events: {
              'click : 'alertBook'
        },

If you need to define events individually for each instance of the view or if a view has different modes of operation, you can use delegateEvents(). This function is called from the View constructor automatically, so you don’t need to call it when your events hash has been defined. Calling delegateEvents will remove any existing callbacks and use the events hash provided to create a new set of event handlers.

The following would change the listener for the alert from a click to a mouseover:

myLibraryView.delegateEvents( {
                'mouseover #book ' : 'alertBook'
       });

You can remove all events by passing an empty events hash to delegateEvents or by calling the undelegateEvents function. By adding a line such as the following to your view, you can remove all the events handled in myLibaryView. Type the following line into your Chrome Developer Tools console, and notice how the view no longer responds to any events you have created handlers for.

myLibraryView.undelegateEvents();

Dealing with self and this

A lot of the code that you will see in Backbone applications will have functions where a reference to the original this object is saved as self.

var self = this;

This is done to maintain a reference to the original this, even when the context changes. You’ll see this happen a lot in closures in your code, especially in any event handlers you create.

Using this approach, the render function would change to use the self reference in place of this.

render: function(){
               var self = this;
               for(vari =0; i<this.collection.size(); i++){
                       self.$el.append('<li id="book">Book Name: ' + self.collection.at(i).get('name') + '</li>'),
               }
                      
        return self;
   },

Backbone View Quick Reference

Table 4-1 describes the properties and functions available in Backbone.View.

Table 4-1. The Most Important Properties and Functions in Backbone.View

Function/Property

Description

el

This specifies areference to the DOM element to be used to contain this view.

$el

This specifies a cached jQuery object for the view’s element.

$(<selector>)

When jQuery is included, the $ function will run queries scoped within the view’s element.

model

This specifies the model that this view should render.

collection

This specifies the collection that the view should render.

id

This specifies the ID assigned to the view’s root element.

className

This specifies the CSS classes for the view’s root elements.

tagName

This specifies the HTML tag for this view’s root element.

attributes

This specifies additional attributes to use for the element. This property can also be used to access the available attributes.

setElement(<selector>)

This changes the root element of this view.

remove()

This removes the view from the DOM completely.

render()

This is the function that deals with all the rendering of the view.

events

This is ahash of events and their handler functions to be used in this view.

delegateEvents(<events>)

This sets a new set of events and handlers for the view, removing the previous events.

undelegateEvents(<events>)

This removes all the view’sevents.

Templating in Backbone

Templating libraries make the separation of logic and presentation even more pronounced. By having templates defined outside of your JavaScript source, you can avoid having a mess of HTML strings in the render methods of your views.

The idea of a templating library is to take JSON objects from your JavaScript application and insert them into anHTML template, which includes conditionals and other logical expressions as well as placeholders for the object values.

Backbone doesn’t force you to use any particular templating library,and as you can see from the previous section, you can just use plain HTML. We’ll look at three templating libraries in this chapter. First we’ll deal with Underscore, which your Backbone application will already depend on. Then we’ll look at Handlebars and Mustache, two of the most popular templating libraries.

Templating with Underscore

As well as providing a number of useful functions for your Backbone application, Underscore contains functionality to deal with templating.

Templates are placed in your HTML page as a script, with a type of text/template so that the templates we create are ignored by the browser as it is rendering the HTML page. The template should also have an ID so that it can be found by your JavaScript.

<script type="text/template" id="library-template">
</script>

Underscore allows you to use JavaScript expressions within the template to loop through data and perform other conditional operations. Consider first what the data looks like in the render method from the previous section. We have a library that contains a number of books. Becausewe want to render a collection, rather than a single model, a loop will be required in the template.

<script type="text/template" id="library-template">
<ul>
   <% for (vari = 0; i<library.length; i++) { %>
     <% var book = library[i]; %>
     <li>
       <b><%= book.name %></b> by <%= book.author %>
     </li>
   <% } %>
 </ul>
</script>

This template expects that the JSON structure passed through for rendering is named library and that it is a collection of one or more items with the attributes as listed earlier (name and author).

Notice how any JavaScript code can be placed within the <% ... %> section, such as the for loop, and how all HTML code appears outside of these sections. Data can then be displayed using <%= variable %> sections.

With the template defined in the HTML, the view needs to be aware of this in the render method. The key to this is the template() function provided by Underscore.

This function compiles the JavaScript template into a function that can be evaluated for rendering. The parameters for the template are the string that represents the template and the data to be rendered, along with an optional parameter for the template settings.

Populating the value of the template string is done by finding the element in the page with the appropriate ID and evaluating the HTML of the result.

$("#library-template").html()

As the template expects the data in a particular structure, with the name ‘library’, the JSON representation of the collection is passed as the second parameter, with the expected identifier.

{'library': self.collection.toJSON()}

Finally, the template can be rendered by appending to the view’s $el attribute.

self.$el.append(output);
  

The full code listing for our Underscore-enabled template function is as follows:

render: function(){
               var self = this;

var output = _.template($("#library-template").html(), {'library': self.collection.toJSON()});
        
        self.$el.append(output);
                      
                return self;
  }

Note that the Underscore library is referred to using the _ namespace throughout the code. The render function defined earlier is straightforward, but it has a flaw: every time render is invoked, the template is compiled. It is neater to store the compiled template as an attribute for your view.

LibraryView = Backbone.View.extend({
        //other view related code
        template: _.template($("#library-template").html()),
        ....
});

Now when the view is created, the template is compiled and is ready for use. This leads to a cleaner render function.

render: function(){
        var self = this;
        var output = self.template({'library': self.collection.toJSON()});
        self.$el.append(output);
        return self;
},

The templateSettings parameter can be used to change the delimiter styles, by using adifferent regular expression in the interpolate parameter. For example, to use {{ }} rather than <% %>, you could use the following settings:

vartemplateSettings = {
 interpolate : /{{(.+?)}}/g
};

These settings can be made global for all Underscore templates by defining them at the _.level.

_.templateSettings = {
 interpolate : /{{(.+?)}}/g
};

This line would be applied to your entire application, so it would need to be declared before any view has been created in your JavaScript source code.

As you can see, using templates with Underscore is quite simple. With pure JavaScript used inside the template for logic and conditions, the codeis really easy to follow. But there are other, more compellingoptions, which we will cover in the following sections.

Templating with Handlebars

Handlebars (www.handlebarsjs.org) is one of the most popular templating libraries in the JavaScript community. The library follows the Mustache.js style, where the philosophy encourages logic-less templates. Note that this is a different approach than Underscore. As a result of this, Handlebars templates will not accept arbitrary JavaScript within the templates, forcing you to use built-in constructs. However, there is the ability to add your own helpers, which we will look at later.

Like all templating libraries, Handlebars accepts the template structure and compiles it to a JavaScript function that accepts JSON data for presentation. One of the advantages of Handlebars is that, in following the same style as Mustache templates, the libraries are interchangeable, while you can keep the same templates. Also, with its template precompilation options, Handlebars is considered one of the most advanced libraries available.

Using Handlebars with Backbone

Including Handlebars in your Backbone project is surprisingly easy. For starters, you’ll need to download the latest version of the library from www.handlebarsjs.org. To match the structure of the code used so far in the book, you can download this to the js/external folder and include it in index.html as follows:

<scriptsrc="js/external/handlebars.js"></script>

Now let’s replace the template we created for Underscore with a Handlebars-compatible version. As before, the template is contained within a <script> tag with an ID, but the type of the template is now text/x-handlebars-template.

<script type="text/x-handlebars-template" id="library-template">

The approach to the loop is where the differences between Handlebars and Underscore are clearest to see, with Handlebars incorporating expressions in the form of {{#<expression name>}}.

<script type="text/x-handlebars-template" id="library-template">
<ul>
        {{#each library}}
       <li>
        <em>{{name}}</em> by {{author}}
     </li>
        {{/each}}
 </ul>
</script>

As you can see from the previous code, Handlebars templates look a lot more elegant than the Underscore equivalent. Rather than using a for statement, the #each expression is used to iterate through the collection, which was passed with the identifier library.

While {{#each}} is used to initiate the loop, it is then terminated using {{/each}}. All blocks in Handlebars follow this pattern. The variables are presented by simply placing the variable name within the curly braces.

If the library object contained another object underneath, its primitive values could be accessed using dot notation. For example, imagine that each book had the following structure, with an object contained in the book to represent the publishing date:

varbookOne = new Book({name: 'Beginning Backbone', author: 'James Sugrue', publishDate :{year: 2013, month: 'December'} });
 

The publish year could then be accessed within the loop using {{publishDate.year}}.

<script type="text/x-handlebars-template" id="library-template">
<ul>
        {{#each library}}
       <li>
        <em>{{name}}</em> by {{author}} published in {{publishDate.year}}
     </li>
        {{/each}}
 </ul>
</script>
 

Including the Handlebars template is as simple as changing the template attribute of the view to compile using Handlebars instead of Underscore.

LibraryView = Backbone.View.extend({
              ....
       template: Handlebars.compile($("#library-template").html()),
              ...
       });

Note how the only change was to replace _.templatewith Handlebars.compile.

In fact, the render method is the same as before, becausethe only code that was tied to the template library was the declaration of the template variable.

render: function(){
        var self = this;
        var output = self.template({'library':self.collection.toJSON()});
        self.$el.append(output);
        return self;
},

As you can see, Handlebars provides a neat way of creating templates. The expression language is straightforward but quite powerful. The following section will give you more insight into what is possible with Handlebars.

A Quick Guide to Handlebars

Sincethe syntax of Handlebars templates requires more than plain JavaScript, this section will go through some of the basic expressions to help get you started.

Displaying Variables

Variable values can be output to the template using the form {{name}}. This will print out the value  name in the current context, which can be altered by block expressions thatloop through collections.

<h1>{{name}}</h1>

If you are dealing with nested variables, you can use dot-separated paths to determine the value. For example, if the template was dealing with a person object, you could display the details as follows:

<h1>{{person.name}}</h1>
<p>Birthday: {{person.birthday}}</p>

Comments

Commentscan be inserted into templates using either {{! comment }} or {{!-- comment --}}.

{{! Name of the person }}
<h1>{{person.name}}</h1>

The {{!-- }} style is used when you need to comment out Handlebars expressions.

{{!-- unused expression for now {{name}} --}}

Block Expressions

Blocks in Handlebars are represented with a {{#expression}}statement anda {{/expression}} statement to complete the block.

each

As we’ve already seen in the library example, the each helper allows a list to be iterated over.

{{#each library}}
       <li>
        <em>{{name}}</em> by {{author}} published in {{publishDate.year}}
     </li>
       {{/each}}

Note that you can use {{this}} within the block to reference the current element that is being iterated through.

You can also access objects and properties outside of the current context by using paths. An example of this would be to use {{../<property name>}} to look at the property that is at the same level as the list you are currently iterating through.

Conditionals

There are a  number of conditional statementsavailable for use in your template definition. The following section lists some of these.

if else

In the event that there are conditional sections of a template to be rendered, Handlebars includes an if else structure. A parameter is passed through to the {{#if }} expression to be evaluated.

{{#ifbook.published}}
       <p>Book now available</p>
       {{else}}
       <p>Book coming soon : {{book.pubishDate}}</p>
       {{/if}}

unless

The unless helper works as the inverse of the if statement shown earlier. It takes a parameter and ensures that it evaluates to false before entering the template section.

{{unlessbook.published}}
<p>This book is not yet published</p>
{{/unless}}
 

Built-in Helpers

Handlebars comes with a few built-in helpers to make it easier to use.

with

The with helper allows the context to be changed within a template so that a particular object is used. Rather than using {{object.property}}, this helper allows you to specify that you are dealing with a particular object within the block in the following form:

{{#with object}}
        {{property}}
        {{/with}}

To see this in action, let’s consider the following Person object:

{{#with person}}
               <h1>{{name}}</h1>
               <p>Birthday: {{birthday}}</p>
       {{/with}}
 

log

The log helper allows simple logging within the template, which can useful for debugging.

The helper delegates to Handlebars.logger.log, which can be overridden if custom logging is required.

{{#with person}}
               <h1>{{log name}}</h1>
       {{/with}}

Providing Helpers

The real power in Handlebars is the ability to write your own helpers in orderto deal with cases where the built-in expressions and helpers are not enough. You can create your own helpers in JavaScript code that will then be used during the compilation of any of your templates.

Let’s create a simple helperthat adds two numbers. You need to use the Handlebars registerHelper function and providethe helper name, followed by the operation that will be carried out.

Handlebars.registerHelper('add', function(param1, param2){
       return param1 + param2
});

You can now use this in your templates as follows:

<p>In 20 years time {{name}} will be {{add person.age 20}} years old </p>

Don’t forget that there’s a huge community of Handlebars users who share their own helpers.

Precompiling Templates

Handlebars provides a powerful precompilation ability that results in time savings for client-side execution and allows you to use the Handlebars runtime library, handlebars.runtime.js, which doesn’t include the runtime compilation capability. At the time of this writing, the unminimizedruntime library was 11KB, while the full Handlebars library was 73KB. When targeting mobile devices, such savings can be significant.

You will need Node.js installed on your development or build machine to run precompilation. In Chapter 3, we created a Node.js server to act as a backend to our application. If you haven’t already installed node.js, you can download it from http://nodejs.org. Once you have node.js installed, you can use the node package manager (NPM) to download the handlebars package.

npm install handlebars -g

All templates will need to be stored in an external file, which is passed to the precompiler on the command line.

handlebars<inputfile> -f <outputfile>

This will result in a JavaScript file being created that contains the compiled template, which can then be included within your application.

Templating with Mustache

Mustache.js is another logic-less templating library, available from http://mustache.github.io. Mustache is popular across a broad spectrum of languages, including Ruby, Java, Objective-C, and many more.

The template format is much the same as that used in Handlebars, although without the helpers.

Using Mustache with Backbone

You will first need to download the latest version of Mustache.js from http://mustache.github.io. Again, to match the conventions used throughout this book, this should be saved in the js/external folder and included in index.html as follows:

<scriptsrc="js/external/mustache.js"></script>

The template will look similar to the Handlebars version.

<script type="text/x-mustache-template" id="library-template">
<ul>
        {{#library}}
       <li>
        <em>{{name}}</em> by {{author}}
     </li>
        {{/library}}
 </ul>
</script>

Note that iteration through the list is achieved using {{#<listname>}} rather than using the {{#each}} block helper that exists in Handlebars. The loop is terminated using {{/<listname>}}. However, everything else is much the same in the template.

Once again, changing the template library from the Backbone view is just a matter of changing the template attribute.

template: Mustache.compile($("#library-template").html()),

The render method remains the same as before.

render: function(){
        var self = this;
        var output = self.template({'library': self.collection.toJSON()});
        self.$el.append(output);
        return self;
},

It’s clear from the previousexample that switching from Handlebars to Mustache, or vice versa, is a relatively straightforward transition.

A Quick Guide to Mustache

This section provides a brief overview of how to achieve a number of commonly used tasks within Mustache templates.

Displaying Variables

Variables are displayed by using the double curly braces syntax, just as in Handlebars.

{{name}}

Dot notation can be used to access properties of an object.

{{person.name}}

Iterating Through Lists

Blocks that will iterate through a listcan be created by initializing a block with the {{#list}} syntax and closing the section using {{/list}}.

{{#library}}
  <li>
   <em>{{name}}</em> by {{author}}
</li>
   {{/library}}

The current object that has focus in the iterated list can be accessed using a single dot.

{{#library}}
          <p>This object {{.}}</p>
{{/library}}

Comments

Mustache templates can contain comment sectionsusing the format {{! comment }}.

{{! Display the person name }}
{{person.name}}

Which Templating Library to Use?

Now that you’ve seen three of the leading options, deciding which templating library to use can be difficult. It really depends on your project’s needs. If you are using limited or very simple templates, use Underscore. Becauseyou will already have a dependency, using Underscore should be the very least you use. Taking advantage of any templating library will lead to a cleaner codebase, with HTML nicely separated from all JavaScript code in your view.

However, if your application is likely to have many different views, it is worth considering Handlebars. The syntax of the templates is more natural, and you always have the ability to add more helpers to suit the requirements of your project. The precompilation functionality offered by Handlebars makes it a compelling choice for projects that are concerned with performance, especially those that include mobile devices as a target.

Summary

This chapter provided an overview of everything that you will need for the presentation layer of your Backbone application. We first covered Backbone.View, which provides logic and rendering capabilities for your Backbone models and collections. After looking at the simplest type of rendering, using plain HTML, we dealt with three of the major templating libraries to see how a cleaner separation of HTML and JavaScript can be achieved. From the simplicity of the included Underscore library to the power of Handlebars, the benefits of templating should now be clear.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.138.202