2012-02-11 2 views
1

Я изучаю javascript и задаюсь вопросом о прослушивании и отправке событий с помощью jQuery.Javascript MVC + прослушивание и отправка событий с помощью jQuery

В моей модели, у меня есть функция, которая вызывает событие изменения:

Model.prototype.setCurrentID = function(currentID) { 
    this.currentID = currentID; 
    $('body').trigger('change'); 
} 

Спусковое событие требует элемента, поэтому я обязан его к «телу». Это хорошая практика или плохая практика?

В AS3, который я больше знаком, я бы просто послать глобальное событие из модели, переходящим в константном значении, прислушиваясь к этому событию с экземпляром модели:

var model:Model = new Model(); 
model.addEventListener(CONST_VALUE, handlerFunction); 

В JQuery, в моем Посмотреть объект, мне нужно прикрепить элемент к слушателю, так что я обвил его в «тело» в очередной раз:

var View = function(model, controller) { 
    var model; 
    var controller; 
    this.model = model; 
    this.controller = controller; 

    $('body').change(function(evt) { updateSomething(evt); }); 

    function updateSomething(evt){console.log('updating...')}; 
} 

Это работает, но я заинтересован в вашем взять на субъект.

+0

Похоже, у вас есть дополнительная правая фигурная скобка «}» в $ ('body'). Change (function (evt) {updateSomething (evt);}); функция updateSomething (evt) {console.log ('update ...')} extra --->} –

ответ

2

Я рекомендую использовать частный диспетчер, который не подвергается публике.
Например, ваша логика может не сработать, если пользователь или плагин развязывает все события на теле (ваш диспетчерский):

$('body').unbind(); 

Этого можно избежать путем создания узла DOM, а не подвергать его до конца пользователь (не присоединять его к йот):

var dispatcher = $('<div />'); 

Model.prototype.setCurrentID = function(currentID) { 
    this.currentID = currentID; 
    dispatcher.trigger('change'); 
} 

var View = function(model, controller) { 
    this.model = model; 
    this.controller = controller; 

    dispatcher.bind('change',function(evt) { updateSomething(evt); }); 
    function updateSomething(evt){console.log('updating...')} 
} 

Еще одна хорошая вещь, чтобы иметь в виду при разработке событийно-программирования приложений с JQuery является то, что JQuery позволяет связывать/триггер пользовательских событий, а также позволяет вам to namespace your events. Таким образом, вы можете управлять более эффективно привязку события и запуск:

Model.prototype.setCurrentID = function(currentID) { 
    this.currentID = currentID; 
    dispatcher.trigger('modelIdChange.' + this.currentID); 
} 
Model.prototype.destroy = function() { 
    // unbind all the event handlers for this particular model 
    dispatcher.unbind('.'+this.currentID); 
} 

var View = function(model, controller) { 
    /*...*/ 

    // this will be triggered for all the changes 
    dispatcher.bind('modelIdChange',function(evt) { updateSomething(evt); }); 

    // this will be triggered only for the model with the id "id1" 
    dispatcher.bind('modelIdChange.id1',function(evt) { updateSomething(evt); }); 

    /*...*/ 
} 
+0

Отлично! Это было очень полезно! – worked

0

Мои возражения:

  • Я бы не связывать события, которые имеют такое же имя, как и Broswer событий, может быть интерференция.
  • Ваш код работает, если у вас есть одна модель, но если у вас есть 2 или более, вы хотите их разделить, а не связывать/запускать оба на одном элементе.

Как насчет:

Model.prototype.bind = function(event, func) { 
    if (!this._element) this._element = $('<div>'); 
    this._element.bind(this.name+'_'+event, $.proxy(func, this)); 
    return this; 
}; 
Model.prototype.trigger = function(event) { 
    if (!this._element) this._element = $('<div>'); 
    this._element.trigger(this.name+'_'+event); 
    return this; 
}; 

Таким образом, вы решить обе. Примечание. Я добавляю this.name+'_' к именам событий (которые предполагают, что каждая модель имеет какое-то имя и гарантирует, что события не совпадают с событиями браузера), но вы также можете удалить префикс.

Я также использую $.proxy в bind, так что this в обработчике событий относится к модели.

var View = function(model, controller) { 
    .... 
    model.bind('change', function() {...}); 
} 
2

Я бы пойти на шаг дальше и создавать собственные глобальные события.С помощью JQuery вы можете вызвать глобальное пользовательское событие так:

$.event.trigger('change'); 

Любой элемент может подписаться на это событие:

$('#myDiv').bind('change', function() { 
    console.log($(this)); 
}); 

this ключевое слово в обработчик событий является элементом DOM, который подписался на сработавшего мероприятие.

+0

Также очень хороший момент! Благодаря! – worked

Смежные вопросы