Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable specific event in a Backbone.js view

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

like image 570
rpabon Avatar asked Feb 20 '23 07:02

rpabon


1 Answers

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, uses this.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.

like image 150
mu is too short Avatar answered Mar 02 '23 03:03

mu is too short