Files
simple-bookreader/client/islets/core/y-event-manager/y-event-manager.js
Oleg Mokhov f3546ef3a5 Release
2015-06-20 14:48:34 +05:00

139 lines
4.8 KiB
JavaScript

modules.define(
'y-event-manager',
[
'inherit',
'y-event-emitter',
'jquery'
],
function (
provide,
inherit,
YEventEmitter,
$
) {
/**
* Адаптер для YEventEmitter, jQuery. Позволяет привязывать обработчики к разным эмиттерам событий
* и отвязывать их, используя вызов одной функции. Менеджер всегда привязан к какому-либо объекту, который
* является контекстом для всех обработчиков.
*
* Полезен, когда нужно отвязать все обработчики сразу. Например, при уничтожении объекта.
*
* @example
* function UserView(model, el) {
* this._eventManager = new YEventManager(this);
*
* // Привязываем обработчик к YEventEmitter
* this._eventManager.bindTo(model, 'change-name', this._changeName);
*
* // Привязываем обработчик к jQuery объекту
* var hideEl = el.find('.hide');
* this._eventManager.bindTo(hideEl, 'click', this._hide);
* }
*
* UserView.prototype.destruct = function () {
* // Удаляем все обработчики
* this._eventManager.unbindAll();
* };
*
* UserView.prototype._changeName = function () {};
*
* UserView.prototype._hide = function () {};
*/
var YEventManager = inherit({
/**
* Создает менджер событий для переданного объекта.
*
* @param {Object} owner Контекст для всех обработчиков событий.
*/
__constructor: function (owner) {
this._owner = owner;
this._listeners = [];
},
/**
* Привязывает обработчик к переданному эмиттеру событий.
*
* @param {YEventEmitter|jQuery} emitter
* @param {String} event
* @param {Function} callback
* @returns {YEventManager}
*/
bindTo: function (emitter, event, callback) {
if (emitter instanceof YEventEmitter) {
this._listeners.push({
type: 'islets',
emitter: emitter.on(event, callback, this._owner),
event: event,
callback: callback
});
} else if (emitter instanceof $) {
var proxy = callback.bind(this._owner);
this._listeners.push({
type: 'jquery',
emitter: emitter.on(event, proxy),
event: event,
callback: callback,
proxy: proxy
});
} else {
throw new Error('Unsupported emitter type');
}
return this;
},
/**
* Отвязывает обработчик от переданного эмиттера событий.
*
* @param {YEventEmitter|jQuery} emitter
* @param {String} event
* @param {Function} callback
* @returns {YEventManager}
*/
unbindFrom: function (emitter, event, callback) {
for (var i = 0; i < this._listeners.length; i++) {
var listener = this._listeners[i];
if (listener.emitter === emitter &&
listener.event === event &&
listener.callback === callback
) {
this._unbind(listener);
this._listeners.splice(i, 1);
break;
}
}
return this;
},
/**
* Отвязывает все обработчики от всех эмиттеров событий.
*
* @returns {YEventManager}
*/
unbindAll: function () {
while (this._listeners.length) {
var listener = this._listeners.pop();
this._unbind(listener);
}
return this;
},
/**
* Отвязывает обработчик события.
*
* @param {Object} listener
*/
_unbind: function (listener) {
switch (listener.type) {
case 'islets':
listener.emitter.off(listener.event, listener.callback, this._owner);
break;
case 'jquery':
listener.emitter.off(listener.event, listener.proxy);
}
}
});
provide(YEventManager);
});