user1473594
user1473594

Reputation: 17

Underscore.js template with Backbone.js error

The line below is completely failing.

template: _.template($('#test').html()),

Trying to follow a simple example from https://github.com/ccoenraets/backbone-jquerymobile to use jQuery mobile along with Backbone.js. The error I'm getting in the web inspector is: TypeError: 'null' is not an object (evaluating 'str.replace') which is in line 913 of the underscore.js. Using is _.template in this fashion:

template: _.template("<h1>To Do</h1>"),

works, but in order to incorporate the jQuery mobile styles, that way won't do.

todo.js

TodoBb.Views.ComCentersTodo = Backbone.View.extend({

template: _.template($('#test').html()),


render: function() {
    $(this.el).html(this.template());
    return this;
}
});

main.html

<script type = 'text/template' id = 'test'> <h1>To Do</h1> </script>

Upvotes: 0

Views: 3716

Answers (1)

mu is too short
mu is too short

Reputation: 434675

The DOM isn't ready when your view is being parsed:

TodoBb.Views.ComCentersTodo = Backbone.View.extend({
    template: _.template($('#test').html()),
    //...
});

so $('#test').html() is null and you're actually doing this:

TodoBb.Views.ComCentersTodo = Backbone.View.extend({
    template: _.template(null),
    //...
});

The internals of _.template use replace while converting the template to a JavaScript function.

You have a few options:

  1. Put the TodoBd.Views.ComCentersTodo definition inside a $(document).ready() handler:

    $(function() {
        TodoBb.Views.ComCentersTodo = Backbone.View.extend({
            template: _.template($('#test').html()),
            //...
        });
    });
    
  2. Don't compile the template until you need it:

    TodoBb.Views.ComCentersTodo = Backbone.View.extend({
        //... no template in here
        render: function() {
            var html = _.template($('#test').html(), this.model.toJSON());
            this.$el.html(html);
            return this;
        },
        //...
    });
    

As a variation of 2, you could cache the compiled template functions somewhere and only call _.template($('#test').html()) the first time you use it.

Upvotes: 2

Related Questions