Reputation: 13908
Template:
<div class="view">
<input id="todo_complete" type="checkbox" <%= completed ? 'checked="checked"' : '' %> />
<label><%= title %></label>
<button class="destroy"></button>
</div>
<input class="edit" value="<%= title %>" />
View:
var TodoView = Backbone.View.extend({
tagName: 'li',
todoTpl: _.template($('#item-template').html()),
events: {
'dblclick label': 'edit',
'keypress .edit': 'updateOnEnter',
'blur .edit': 'close'
},
initialize: function() {
console.log('Todo View initialized!');
this.$el = $('#todo');
console.log(this.$el);
this.render();
},
render: function() {
console.log('Todo View render started...');
console.log(this.model.attributes);
this.$el.html(this.todoTpl(this.model.attributes));
},
edit: function() {console.log('edit called!');},
close: function() {console.log('close called!');},
updateOnEnter: function(e) {
console.log(e);
}
});
There are no events when the page loads, and I'm able to see the rendered template. However if I double click on the label
, keypress on the input
or blur the other input, nothing happens. I'm expecting to see a log in the console. What am I doing wrong?
Upvotes: 1
Views: 204
Reputation: 434685
You lose your event bindings when you:
this.$el = $('#todo');
You're not supposed to directly assign to the $el
or el
properties, you're supposed to call setElement
instead:
setElement
view.setElement(element)
If you'd like to apply a Backbone view to a different DOM element, use setElement, which will also create the cached
$el
reference and move the view's delegated events from the old element to the new one.
Also, if you're going to be changing the view's el
then there's no need for a tagName
property. You could also specify the el
when you create the view:
new TodoView({ el: '#todo' });
new TodoView({ el: $('#todo') });
If your #todo
is actually the <ul>
or <ol>
then:
tagName
alone.el
to $('#todo')
by calling append
instead of calling setElement
.If this is the case then your code would look more like this:
var TodoView = Backbone.View.extend({
tagName: 'li',
//...
initialize: function() {
console.log('Todo View initialized!');
this.render();
},
//...
});
// And then where you create the view...
var v = new TodoView(...);
$('#todo').append(v.el);
Upvotes: 1
Reputation: 13908
So I was able to solve this problem by adding el
to the properties passed into Backbone.View
:
var TodoView = Backbone.View.extend({
tagName: 'li',
// ...
el: $('#todo')
// ..
});
Upvotes: 0