在backbone视图中绑定多个事件类型

28
我想知道在backbone中是否有可能在一行内绑定多个事件类型。
考虑以下代码:
var MyView = Backbone.View.extend({
    id: 'foo',
    events: {
        'click .bar': 'doSomething',
        'touchstart .bar': 'doSomething'
    },
    doSomething: function(e) {
        console.log(e.type);
    }
});

我想知道是否有可能将'click'和'touchstart'事件绑定合并成一行,例如:

events: { 'click,touchstart .bar': 'doSomething' }

欢迎提出任何建议。


你是否在这里 http://documentcloud.github.com/backbone/#Events 检查了 Trigger 部分?但在你的情况下,将绑定放在视图的 initialize 方法中。 - Deeptechtons
我已经在大多数视图的初始化方法中编写了相当数量的代码,因此出于个人喜好,我更愿意避免在那里绑定事件。 - stephenmuss
寻找正确的触发器链接的人可以访问:http://backbonejs.org/#Events-trigger - user823447
3个回答

18

1
是的,我知道可以使用模型来实现这个。但是在backbone视图的事件声明中真的不可能吗?我也不想在视图的initialize方法中绑定视图。我很好奇其他人是否有什么看法,无论它是否可能。但如果像你说的那样不可能,我会尝试扩展Backbone.View。 - stephenmuss
您可以在注释源代码中查看delegateEvents的工作原理。您还可以将视图的events属性定义为返回事件哈希的函数。 - rinat.io
是的,不可能,实际上delegateEvents实现仅基于一种_key_结构。 - fguillen
只是出于好奇,你不能在你的事件中单独列出它们吗:{}?还是你只是尽可能地想要减少你的代码量? - jmk2142

15

对于任何感兴趣的人,我最终重写了Backbone.View中的delegateEvents方法。

只需要修改一些行就可以得到所需的功能。

您可以在我的Github提交记录中查看差异。

这里是已修改的delegateEvents方法:

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);
            }
        });
    }
}

1
我们也可以按照以下方式实现。 优点是可以管理每个事件之间的空间。

在Github上提交此处

直接在Backbone中添加:

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;
}

覆盖 delegateEvents 方法:

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;
};

我们现在可以用一行代码管理事件:
events: { 
    'click a[data-anchor], wheel, keydown': 'scroll'
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接