Reputation: 2134
I am trying around with Backbone.js and get along so far, but I have got a problem.
Lets say I got a root element and a child element.
When the document loads, I create 3 "root" instances. The root instance appends a tag. Each root instance creates one child instance which creates a
Now I would like the child instance to attach and onclick event to the
I created a fiddle:
http://jsfiddle.net/Fluxo/sEjE5/17/
var child = Backbone.View.extend({
template: _.template('<li>Item '+count+'</li>'),
events: {
'click li': function() {
alert('listitem Click Child Element');
}
},
initialize: function() {
_.bindAll('render');
this.render();
}, render: function() {
this.$el.html(this.template())
}
});
var root = Backbone.View.extend({
template: _.template('<div><h3>List</h3><p /><ul></ul><hr />'),
events: {
'click li': function() {
alert('listitem Click - Root Element');
}
},
initialize: function() {
_.bindAll('render');
this.render();
},
render: function() {
this.$el.html(this.template());
$('body').append(this.el);
var item = new child();
this.$el.find('ul').append(item.$el.html());
}
});
The events created in the root element will fire, but not the ones in the child element.
Am I doing anything wrong?
Upvotes: 1
Views: 3096
Reputation: 434665
You're doing two things wrong.
First of all, your child
is an <li>
, it doesn't contain an <li>
:
template: _.template('<li>Item '+count+'</li>'),
events: {
'click li': ...
},
so your click li
event won't do anything. Events are bound to the view's el
using delegate
:
delegateEvents
delegateEvents([events])
Uses jQuery's
delegate
function to provide declarative callbacks for DOM events within a view. [...] Omitting theselector
causes the event to be bound to the view's root element (this.el
).
So if you want to bind a click handler directly to the view's el
rather than one of its children, you want to leave out the selector:
events: {
'click': ...
}
The next problem is that you're not actually inserting the child
element into the DOM, you're copying the HTML:
this.$el.find('ul').append(item.$el.html());
By appending item.$el.html()
instead of item.el
, you're grabbing the correct HTML as a string and inserting that HTML but you lose the events in the process; the events are bound to the DOM object, item.el
, not to the HTML string. You can fix this by appending item.el
:
this.$el.find('ul').append(item.el);
// Or you could say, the two approaches are the same
this.$('ul').append(item.el);
Demo: http://jsfiddle.net/ambiguous/K76JM/ (or http://jsfiddle.net/ambiguous/kFxHQ/)
Upvotes: 5