Here's a template I'm using
<script type="text/template" id="template-message">
<p class="message"><%= message %></p>
</script>
Here's my Backbone.View
var MessageView = Backbone.View.extend({
template: _.template(Backbone.$("#template-message").html()),
render: function() {
this.$el.html(this.template(this.model.attributes));
return this;
},
});
How I'm using it
var msg = new Message({message: "hello"}),
view = new MessageView({model: msg});
$("body").append(view.render().el);
Output
<body>
<div>
<p class="message">
hello
</p>
</div>
</body>
I understand why it's happening (the default tagName for a view is div
), but I don't want the wrapper div
on there. I would like to see this as the output
<body>
<p class="message">
hello
</p>
</body>
I'm aware that I could have this in my view
var MessageView = Backbone.View.exntend({
tagName: "p",
className: "message",
// ...
});
The end user will be define the templates, so I don't want those things to be specified in the Backbone.View source code.
How can I get the desired output and still bind the view to the html?
Thanks to @Gohn67's comment, I was able to get this working
var MessageView = Backbone.View.extend({
template: _.template(Backbone.$("#template-message").html()),
initialize: function() {
this.setElement(this.template(this.model.attributes));
}
});
If we take a look at the Backbone Source Code, we can see it setElement
does everything we want it to do
// backbone source code
setElement: function(element, delegate) {
if (this.$el) this.undelegateEvents();
this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
this.el = this.$el[0];
if (delegate !== false) this.delegateEvents();
return this;
},
It even handles the event delegation. Cool!
I recently had to implement this on jQuery 1.3.2. Gross, I know, but it was a simple fix.
The only part that changes is the setElement
bit
initialize: function() {
this.setElement(
$( this.template(this.model.attributes) )
);
}
The template
result must be wrapped in $()
in order to work. I know, it doesn't make a lot of sense considering Backbone is already trying to do this automatically. It's the only thing I could do to make it work with jQuery 1.3.2 though.