Reputation: 1201
I am working on a nested backbone view, in which if you click on, it will create a new instance of the same view. I want to disable only a specific event, not all of them; in this case, the click. I tried using undelegateEvents(), but this will disable all the functions. Any ideas on how can this be done?
Here is a piece of the code I am working on:
var View = Backbone.View.extend({
events: {
"mousedown": "start",
"mouseup": "over"
},
start: function() {
var model = this.model;
var v = new View({
model: model,
});
v.undelegateEvents(); //I just want to disable mousedown
v.render();
},
over: function() {
/*
some code here
*/
},
render: function() {
/*
some code here
*/
}
});
The idea is to ban clicking in the second instantiated view while keeping the other events. The first one will have all of its events.
Thanks
Upvotes: 4
Views: 4948
Reputation: 1910
Here is a simple example that shows how to delegate or undelegate events within a Backbone view
Backbone.View.extend({
el: $("#some_element"),
// delete or attach these as necessary
events: {
mousedown: "mouse_down",
mousemove: "mouse_move",
mouseup: "mouse_up",
},
// see call below
detach_event: function(e_name) {
delete this.events[e_name]
this.delegateEvents()
},
initialize: function() {
this.detach_event("mousemove")
},
mouse_down: function(e) {
this.events.mousemove = "mouse_move"
this.delegateEvents()
},
mouse_move: function(e) {},
mouse_up: function(e) {}
})
Upvotes: 1
Reputation: 434665
You can specify the events you want to use when you call delegateEvents
:
delegateEvents
delegateEvents([events])
Uses jQuery's
delegate
function to provide declarative callbacks for DOM events within a view. If an events hash is not passed directly, usesthis.events
as the source.
So you could do something like this:
var v = new View({
model: model,
});
v.undelegateEvents();
var e = _.clone(v.events);
delete e.mousedown;
v.delegateEvents(e);
v.render();
You might want to push that logic into a method on View though:
detach_mousedown: function() {
this.undelegateEvents();
this.events = _.clone(this.events);
delete this.events.mousedown;
this.delegateEvents();
}
//...
v.detach_mousedown();
You need the this.events = _.clone(this.events)
trickery to avoid accidentally altering the "class's" events
(i.e. this.constructor.prototype.events) when you only want to change it for just one object. You could also have a flag for the View
constructor that would do similar things inside its initialize
:
initialize: function() {
if(this.options.no_mousedown)
this.detach_mousedown()
//...
}
Another option would be to have a base view without the mousedown
handler and then extend that to a view that does have the mousedown
handler:
var B = Backbone.View.extend({
events: {
"mouseup": "over"
},
//...
});
var V = B.extend({
events: {
"mousedown": "start",
"mouseup": "over"
},
start: function() { /* ... */ }
//...
});
You'd have to duplicate the B.events
inside V
or mess around with a manual extend
on the events
as _.extend
won't merge the properties, it just replaces things wholesale.
Upvotes: 7