Underscore template throwing variable not defined error

I've watched some videos on the topic of backbone js. This is an example straight from the video. It is from 2012, so I'm thinking backbone rules/library have changed, but I can't figure out why this does not work at the moment. In the video, the person shows it running in the JS Fiddle, but I can't get it to work. (I've included the necessary libraries in JS Fiddle, i.e. underscore, backbone and jQuery)

var V = Backbone.View.extend({
  el:'body',
  render: function () {
  	var data = { lat: -27, lon: 153 };
    this.$el.html(_.template('<%= lat %> <%= lon%>', data));
    return this;
  }
});

var v = new V();

v.render();
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>

Answers:

Answer

You used to be able to parse and fill in an Underscore template in one go like this:

var html = _.template(template_string, data);

But as of Underscore 1.7.0, the second argument to _.template contains template options:

template _.template(templateString, [settings])

Compiles JavaScript templates into functions that can be evaluated for rendering. [...] The settings argument should be a hash containing any _.templateSettings that should be overridden.

You have to compile the template using _.template and then execute the returned function to get your filled in template:

var tmpl = _.template(template_string);
var html = tmpl(data);

// or as a one-liner, note where all the parentheses are
var html = _.template(template_string)(data);

In your case, it would look something like this:

var V = Backbone.View.extend({
  el:'body',
  render: function () {
    var data = { lat: -27, lon: 153 };
    var tmpl = _.template('<%= lat %> <%= lon %>');
    this.$el.html(tmpl(data));
    return this;
  }
});

var v = new V();

v.render();
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.0/backbone-min.js"></script>

Answer

This can be useful

1: If you have more then one template or sometime you are using external template so it can be useful for you inside method you can write reusable code

var V = Backbone.View.extend({
    el:'body',
    temp: function (str) {

        // reusable code
        return _.template(str);
    },
    render: function () {
        var data = { lat: -27, lon: 153 };

        // calling your view method temp        
        var tmpl = this.temp('<%= lat %> <%= lon %>');
        this.$el.html(tmpl(data));

        return this;
    }
});

var v = new V();
v.render();

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.