Binding multiple event types in backbone views

那年仲夏 提交于 2019-12-03 04:25:22
rinat.io

It's impossible for views jQuery events, which are bound through delegateEvents. It's is possible for backbone events, though:

book.on("change:title change:author", ...);

For anyone interested I ended up overriding delegateEvents in Backbone.View.

There are only a few modified lines to get the desired functionality.

You can see a diff in my commit on github

Here is delegateEvents in its modified state:

delegateEvents: function(events) {
    if (!(events || (events = getValue(this, 'events')))) return;
    this.undelegateEvents();
    for (var key in events) {
        var method = events[key];
        if (!_.isFunction(method)) method = this[events[key]];
        if (!method) throw new Error('Method "' + events[key] + '" does not exist');
        var match = key.match(delegateEventSplitter);
        var eventTypes = match[1].split(','), selector = match[2];
        method = _.bind(method, this);
        var self = this;
        _(eventTypes).each(function(eventName) {
            eventName += '.delegateEvents' + self.cid;
            if (selector === '') {
              self.$el.bind(eventName, method);
            } else {
                self.$el.delegate(selector, eventName, method);
            }
        });
    }
}

We could also do it as below. With the advantage to manage space between each event.

Github commit here

Add it in Backbone directly :

delegateEvents: function(events) {
  events || (events = _.result(this, 'events'));
  if (!events) return this;
  this.undelegateEvents();
  for (var key in events) {
    var method = events[key];
    if (!_.isFunction(method)) method = this[method];
    if (!method) continue;
    var match = key.match(delegateEventSplitter);
    this.delegate(match[1], match[2], _.bind(method, this));
  }
  return this;
}

Override delegateEvents method :

Backbone.View.prototype.originalDelegateEvents = Backbone.View.prototype.delegateEvents;
Backbone.View.prototype.delegateEvents = function(events) {
    events || (events = _.result(this, 'events'));
    if (!events) return this;
    this.undelegateEvents();
    for (var key in events) {
        var method = events[key], combinedEvents = key.split(',');
        if (!_.isFunction(method)) method = this[method];
        if (!method) continue;

        for(var i = 0, match = null; i < combinedEvents.length; ++i) {
            match = combinedEvents[i].trim().match(/^(\S+)\s*(.*)$/);
            this.delegate(match[1], match[2], _.bind(method, this));
        }
    }
    return this;
};

We could now manage events in one line :

events: { 
    'click a[data-anchor], wheel, keydown': 'scroll'
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!