Reputation: 3421
EDIT: Forgot to remind the reader that I remembered to set templateSettings as follows:
_.templateSettings = {
interpolate : /\{\{([\s\S]+?)\}\}/g
};
I'm having a hard time getting a varialbe to interpolate in underscore, while running my Jasmine specs. Given the template, rendering method, and jasmine test below, I am able to get the template to interpolate variables properly via:
_.template(
boneHeaderInstance.template.html(),
{ id:boneHeaderInstance.id,
columns:boneHeaderInstance.columns
}
)
While this fails to interpolate the columns variable:
boneHeader = Backbone.View.extend({
el: $('#boneTableHeader'),
template: $('#boneTableHeaderTemplate'),
initialize: function(){
this.id = 'boneTableHeader';
this.el = $( '#' + this.id );
this.columns = 'blah';
this.template = $( '#' + this.id + 'Template' );
this.render();
return this;
},
render: function(){
var that = this;
var data = {id: that.id, columns: that.columns}
this.el.html( _.template( this.template.html(), data ) );
}
});
Template:
<script type = 'text/template' id = 'boneTableHeaderTemplate'>
<tr id = "{{obj.id}}Row">
{{obj.columns}}
</tr>
</script>
In Render Method:
render: function(){
var that = this;
var data = {id: that.id, columns: that.columns}
this.el.html( _.template( that.template.html(), data ) );
}
Jasmine Test:
describe('boneHeader', function(){
beforeEach(function(){
boneHeaderInstance = boneTableInstance.header;
});
describe('rendering', function(){
it('should have expected html', function(){
expect(
boneHeaderInstance.el.html().replace(/\s\t\n/ , '', 'g')
).toEqual(
_.template(boneHeaderInstance.template.html(),
{ id:boneHeaderInstance.id,
columns:boneHeaderInstance.columns
}).replace(/\s\t\n/ , '', 'g')
);
});
});
});
Jasmine Result:
Expected ' <tr id="boneTableHeaderRow"></tr> ' to equal ' <tr id = "boneTableHeaderRow"> blah </tr> '
Upvotes: 0
Views: 2087
Reputation: 434965
You have various problems. First of all, Underscore uses <% %>
for templates unless you change it with something like:
_.templateSettings = {
interpolate : /\{\{(.+?)\}\}/g
};
So your template should look like this:
<script type = 'text/template' id = 'boneTableHeaderTemplate'>
<tr id = "<%= obj.id %>Row">
<td><%= obj.columns %></td>
</tr>
</script>
I've also fixed the HTML error you had in your template, you can't have a text node as an immediate child of a <tr>
and there's no telling what sort of chicanery a browser will get up to if you try such a thing.
Secondly, _.template()
is usually used to return a compiled version of a template and that compiled version is a function that you execute to get the final HTML:
var t = _.template(some_template_html);
var html = t(data);
So you probably want something like this in your constructor:
this.template = _.template($('#' + this.id + 'Template').html());
and this in your render
:
this.el.html(this.template(data));
You can do it all at once with _.template(template_html, context)
though.
Thirdly, you're referencing obj.id
and obj.columns
in your template but you're only giving it id
and columns
so either drop the obj.
prefixes from your template or alter data
thusly:
var data = {
obj: {
id: that.id,
columns: that.columns
}
};
Demo: http://jsfiddle.net/ambiguous/NYLqH/
You'll have to fix your test to account for the corrected HTML of course.
Upvotes: 2