Search code examples
javascriptajaxbackbone.js

Load template by URL in backbone js


I have created a View in backbone to render a collection. It uses a template to format data and the template HTML is written in a string variable. Now the template is becoming complex and I need to store it in a separate file. Is there any way in backbone to load template from URL and what is the best design pattern in this scenario. Following is the code:

var PageView = Backbone.View.extend({
    template: _.template("<% _.each(items,function (item) { %><tr><td><%= item.page_id %></td><td><%= item.title %></td></tr><% }); %>"),

    initialize: function () {
        _.bindAll(this, 'render');
        this.model.bind('all', this.render);
    },

    render: function () {
        this.$el.html(this.template({
            items: this.model.toJSON()
        }));
    }

});

Is there anything like templateURL so that it can be loaded dynamically from another file on server.


Solution

  • Backbone itself does not provide a way to do this, but there are a number of different ways to accomplish this and there are plenty of examples on how to set up the required mechanisms.

    If you choose to use RequireJs (and I would advise you to do so eventually… taking into consideration you will need some time to learn it) you will also need RequireJS’s text plugin. There is a tutorial for using RequireJS and the text plugin in backbone projects available at backbone tutorials.

    After setting up the project loading external templates in a backbone view is as simple as defining them as a dependency of the view and passing that dependency to a variable (projectListTemplate in the following example):

    define([
      'jquery',
      'underscore',
      'backbone',
      // Using the Require.js text! plugin, we load raw text
      // which will be used as our views primary template
      'text!templates/project/list.html'
    ], function($, _, Backbone, projectListTemplate){
      var ProjectListView = Backbone.View.extend({
        el: $('#container'),
        render: function(){
          // Using Underscore we can compile our template with data
          var data = {};
          var compiledTemplate = _.template( projectListTemplate, data );
          // Append our compiled template to this Views "el"
          this.$el.append( compiledTemplate );
        }
      });
      // Our module now returns our view
      return ProjectListView;
    });
    

    Another possible approach, if you don’t feel ready to use RequireJS and you want to move the templates to different files right away would be to use a simple custom template loader. Christophe Coenraets wrote his own and used it in an example backbone project. He made all the source code available on github and he also provides tutorials and explanations.

    He wrote about his method for externalizing templates, in the the first section “Externalizing Templates”.