2012-05-30 4 views
25

Мне было интересно, можно ли связать несколько типов событий в магистрали в пределах одной строки.Связывание нескольких типов событий в базовых представлениях

Рассмотрим следующий пример:

var MyView = Backbone.View.extend({ 
    id: 'foo', 
    events: { 
     'click .bar': 'doSomething', 
     'touchstart .bar': 'doSomething' 
    }, 
    doSomething: function(e) { 
     console.log(e.type); 
    } 
}); 

В основном то, что я интересно, если это возможно совместить событие связывания для «нажмите» и «touchstart» в одну линию - по линии:

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

Любые предложения будут оценены.

+0

Вы проверили раздел ** Trigger ** здесь http://documentcloud.github.com/backbone/#Events. Но в вашем случае выполните привязку в методе инициализации Views. – Deeptechtons

+0

У меня уже есть достойный код в большинстве методов инициализации моих представлений, поэтому я предпочел бы не связывать события там как предпочтение. – stephenmuss

ответ

15

Для тех, кто заинтересован, я в конечном итоге переопределение delegateEvents в Backbone.View.

Для получения желаемой функциональности имеется только несколько модифицированных линий.

Вы можете увидеть различия в моем commit on 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); 
      } 
     }); 
    } 
} 
15

Невозможно просмотреть события jQuery, которые связаны через delegateEvents. Это является possible for backbone events, хотя:

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

Да, я знаю, что могу сделать это с помощью моделей. Но действительно ли это невозможно в объявлении событий в режиме позвоночника? Я также предпочел бы не выполнять привязку к представлению в методе инициализации представления. Мне любопытно посмотреть, что другие могут сказать, возможно ли это или нет. Но если, как вы говорите, я не попытаюсь сделать некоторое расширение Backbone.View – stephenmuss

+0

Вы можете проверить, как ['delegateEVents'] (http://documentcloud.github.com/backbone/docs/backbone.html) работает в аннотированном исходном коде. Вы также можете определить свойство 'events' представления как функцию, которая возвращает хеш события. –

+0

Да, не возможно, фактическая реализация [delegateEvents] (https://github.com/documentcloud/backbone/blob/master/backbone.js#L1230-1247) основана только на одном виде структуры _key_. – fguillen

1

Мы также могли бы сделать это, как показано ниже. Преимущество управления пространством между каждым событием.

Github commit here

Добавьте его в 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; 
} 

Override метод 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' 
}