Reputation: 9476
Moving from a framework-less world to Backbone.js, I've brought along the practice of "caching" my jQuery objects by always storing a reference to them (for efficiency).
var myCachedEl = $('#element');
myCachedEl.on('click', function() {
myCachedEl.html('That tickles.');
});
In Backbone, this is how I might cache my jQuery objects:
var RandomView = Backbone.View.extend({
intitialize: function() {
this.$lastRoll = this.$el.find('#last-roll');
this.listenTo(this.model, 'change', this.render);
},
render: function() {
this.$lastRoll.html(this.model.get('lastRoll'));
},
events: {
'click #last-roll': function() {
this.model.roll();
}
}
});
var randomView = new RandomView({
el: '#random-view',
model: random
});
Given my current setup, I would like to do something akin to...
events: {
'click this.$lastRoll': function() {
// ...
}
}
...where, in my events, I could bind a click event to a cached element. However, the above syntax does not work. I suspect there may be some way to "officially" define sub-elements, so that I could use some syntax akin to what is above.
Question: Is there a "better," "cleaner," or more "Backbone-semantic" pattern, for caching my View's sub-elements, that I could/should follow, instead of my current pattern?
Upvotes: 1
Views: 768
Reputation: 3012
You are caching your elements correctly. Simply, the syntax to bind event handlers doesn't work the way you propose in your question. Because it works in a different way.
All the events that you define with events: { ... }
are bound to the the view's root element el
, and not to the child element last-roll
. When an event fires within your view, it will bubble up to the root element, and there the handler will decide if the target
of the event matches the selector. For example, in your code:
events: {
'click #last-roll': function...
}
binds a click event to RandomView
, and when a click occurs, it will check if the target is last-roll
(ie, matches the selector) and if this is true your handler will be invoked. That's why you pass selectors and not elements there. It's efficient, so go for it.
If you still need to bind events to other elements (such as document
for global keypress event handling or the likes) you can use jQuery's on
or Backbone's listenTo
. With on
you have to remember to deregister your handlers by using off
when removing your view to prevent memory leaks, while with listenTo
you can rely on the automatic cleanup made by Backbone itself.
Upvotes: 2