Working through the setElement
part of Addy Osmani's backbone.js tutorial.
He presents this example:
// We create two DOM elements representing buttons
// which could easily be containers or something else
var button1 = $('<button></button>');
var button2 = $('<button></button>');
// Define a new view
var View = Backbone.View.extend({
events: {
click: function(e) {
console.log(view.el === e.target);
}
}
});
// Create a new instance of the view, applying it
// to button1
var view = new View({el: button1});
// Apply the view to button2 using setElement
view.setElement(button2);
button1.trigger('click');
button2.trigger('click');
However, he doesn't explain why there is different output for button1.trigger('click');
vs. button2.trigger('click');
-- possibly a dumb question, and I know that these are different ways of attaching the view to the button elements, but why does button2.trigger('click');
also return true
?
button1.trigger('click');
shouldn't produce any output at all from that code.
setElement
is fairly simple:
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.
So view.setElement(e)
does four things:
events
from view.el
.view.el = e
.view.$el = Backbone.$(e)
.events
to the new view.el
.The result is that nothing will be left listening to events from button1
and view
will be listening to events from button2
.
A more thorough example might help so let us attach some more click event handlers:
var button1 = $('<button id="button1"></button>').click(function() {
console.log('button1 jQuery', this);
});
var button2 = $('<button id="button2"></button>').click(function() {
console.log('button2 jQuery', this);
});
var View = Backbone.View.extend({
events: {
click: function(e) {
console.log('Backbone ', view.el, view.el === e.target);
}
}
});
var view = new View({el: button1});
view.setElement(button2);
button1.trigger('click');
button2.trigger('click');
Demo: http://jsfiddle.net/ambiguous/S7A9z/
That should give you something like this in the console:
button1 jQuery <button id="button1"></button>
button2 jQuery <button id="button2"></button>
Backbone <button id="button2"></button> true
Both raw jQuery event handlers will be triggered as expected but we'll only get the button2
event through Backbone because the setElement
call happened before the trigger
calls.
So why is view.el === e.target
true? Well, you're clicking on button2
so e.target
will be button2
and the view.setElement(button2)
call replaces view.el
so this.el
inside the Backbone click
handler will also be button2
.