Ответ 1
Как правило, я бы не ответил на архитектурный вопрос с конкретной реализацией (особенно в зависимости от сторонней библиотеки, такой как jQuery), но поскольку моя реализация способствует повторному использованию - и мы говорим о шаблонах здесь - я представлю маленький плагин jQuery, $.eventable, который увеличивает объекты JavaScript с помощью методов события jQuery.
Этот плагин позволит вам реализовать возможность обработки событий для любого объекта (или экземпляра класса) одним простым вызовом.
jQuery.eventable = function (obj) {
// Allow use of Function.prototype for shorthanding the augmentation of classes
obj = jQuery.isFunction(obj) ? obj.prototype : obj;
// Augment the object (or prototype) with eventable methods
return $.extend(obj, jQuery.eventable.prototype);
};
jQuery.eventable.prototype = {
// The trigger event must be augmented separately because it requires a
// new Event to prevent unexpected triggering of a method (and possibly
// infinite recursion) when the event type matches the method name
trigger: function (type, data) {
var event = new jQuery.Event(type);
event.preventDefault();
jQuery.event.trigger(event, data, this);
return this;
}
};
// Augment the object with jQuery event methods
jQuery.each(['bind', 'one', 'unbind', 'on', 'off'], function (i, method) {
jQuery.eventable.prototype[method] = function (type, data, fn) {
jQuery(this)[method](type, data, fn);
return this;
};
});
Если вы включите этот фрагмент, вы можете реализовать свое решение следующим образом:
var MODULE = function() {
// private
var _field1;
var _field2;
function localFunc(p) {
alert('localFunc');
}
// public
return $.eventable({
// properties
prop1: _field1,
// public methods
method1: function(p) {
alert('method1 says:' + p);
this.trigger('myEvent1');
},
method2: function(p) {
alert('method2 doing stuff');
localFunc(p);
this.trigger('myEvent2');
}
});
} ();
// register for events
MODULE.on("myEvent1", function() {
alert('fired1');
});
MODULE.on("myEvent2", function() {
alert('fired2');
});
// use module (only event1 should fire!)
MODULE.method1("hello");
Теперь ваш MODULE имеет следующие вызываемые методы:
MODULE.on(event, /* data, */ handler);
MODULE.bind(event, /* data, */ handler);
MODULE.one(event, /* data ,*/ handler);
MODULE.off(event, handler);
MODULE.unbind(event, handler);
MODULE.trigger(event /*, data */);
Если событие представляет собой список событий, разделенных пробелами, обработчик - это ваш обратный вызов, а данные - необязательное значение для передачи ваших обратных вызовов.
Более подробную информацию можно найти в документации jQuery.