Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I properly store a javascript template, so that it isn't instantiated multiple times

I'm using Backbone and therefore Underscore to render my templates. My templates get rendered in <script> tags and then I use jQuery to grab their html. My backbone view looks like this:

App.ItemView = Backbone.View.extend({
    className:'well',

    events: {
        'click .continue': 'handleContinueClick',
    },

    initialize: function() {
        this.template = _.template($("#ItemTemplate").html())
        this.render()
    },

    render: function() {
        $(this.el).html(this.template({model:this.model}))
    },

    handleContinueClick: function(e) {
        alert('Clicked!')
    }
})

My Issue is I would like to only go and grab the html once and only once for this particular type of view so that if I have a lot of items it doesn't go searching the html for this template each time.

Basically how do I properly store the template variable at the ItemView object level (not instance of the view) keeping in mind that the retrieval of the html has to wait until after page load (so that I can guarantee the template html is available).

like image 365
MattoTodd Avatar asked Mar 23 '12 02:03

MattoTodd


People also ask

What is template based in JavaScript?

JavaScript templating refers to the client side data binding method implemented with the JavaScript language. This approach became popular thanks to JavaScript's increased use, its increase in client processing capabilities, and the trend to outsource computations to the client's web browser.

Can you use JavaScript in Django template?

Django templates are often used to pass data to JavaScript code.


3 Answers

You can build a very simple object that caches the templates for you:


TemplateCache = {
  get: function(selector){
    if (!this.templates){ this.templates = {}; }

    var template = this.templates[selector];
    if (!template){
      var tmpl = $(selector).html();
      template = _.template(tmpl);
      this.templates[selector] = template;
    }

    return template;
  }
}

Then in your view, you can call TemplateCache.get and pass in your template selector.


Backbone.View.extend({
  template: "#ItemTemplate",

  render: function(){
    var template = TemplateCache.get(this.template);
    var html = template(this.model.toJSON());
    this.$el.html(html);
  }
});

The first time you call TemplateCache.get for a given selector, it will load it from the DOM. Any subsequent calls to get the template will load it from the cached version and prevent the extra DOM access call.

FWIW: I have a much more robust version of the TemplateCache object in my Backbone.Marionette framework: https://github.com/derickbailey/backbone.marionette

like image 151
Derick Bailey Avatar answered Oct 19 '22 12:10

Derick Bailey


Most Backbone examples I've seen do it like this. This will only traverse the DOM once to parse the template when the page finishes loading and use that for each new ItemView().

App.ItemView = Backbone.View.extend({
    template: _.template($("#ItemTemplate").html()),

    className:'well',

    events: {
        'click .continue': 'handleContinueClick',
    },

    ...
});

http://backbonejs.org/docs/todos.html#section-21

like image 37
abraham Avatar answered Oct 19 '22 13:10

abraham


You could muck around with prototype.template by hand and compile the template the first time you create an instance of your view. Something like this:

initialize: function() {
    if(!this.constructor.prototype.template)
        this.constructor.prototype.template = _.template($("#ItemTemplate").html());
    this.render();
}

Demo: http://jsfiddle.net/ambiguous/e6y3F/

The trick is to get your hands on the right prototype.

like image 1
mu is too short Avatar answered Oct 19 '22 13:10

mu is too short