I'm implementing the module pattern, and would like to know the best/preferred way to define and register event listeners/handlers. The following works, but maybe there is a better/simpler way...
var MODULE = function() {
// private
var _field1;
var _field2;
function localFunc(p) {
alert('localFunc');
}
// public
return {
// properties
prop1: _field1,
// events
myEvent1Handler: {},
myEvent1: function() {myEvent1Handler();},
myEvent2Handler: {},
myEvent2: function() {myEvent2Handler();},
addListener: function (event,func) {
if (event == "myEvent1")
myEvent1Handler = func;
if (event == "myEvent2")
myEvent2Handler = func;
},
// public methods
method1: function (p) {
alert('method1 says:' + p);
MODULE.myEvent1();
},
method2: function (p) {
alert('method2 doing stuff');
localFunc(p);
MODULE.myEvent2();
}
};
}();
// register for events
MODULE.addListener("myEvent1",function(){alert('fired1');});
MODULE.addListener("myEvent2",function(){alert('fired2');});
// use module (only event1 should fire!)
MODULE.method1("hello");
Try it out:
http://jsfiddle.net/RqusH/3/
Seems like a lot of work to have myEventx, myEventHandlerx, and addListener?
A web page respond according to an event occurred. Some events are user generated and some are generated by API's. An event listener is a procedure in JavaScript that waits for an event to occur. The simple example of an event is a user clicking the mouse or pressing a key on the keyboard.
The module pattern in JavaScript is one of the most used design patterns, used for keeping groups of code independent from each other. Modules allow us to break up different parts of our code to make it easier to maintain and understand. Thus enabling us to keep units of our code clean, separated, and organized.
Normally, I wouldn't respond to an architectural question with a specific implementation (especially one dependent on a 3rd-party library like jQuery), but since my implementation promotes reusability — and we are talking patterns here — I will present a small jQuery plugin, $.eventable, which augments JavaScript objects with jQuery's event methods.
This plugin will allow you to implement event handling capability on any object (or class instance) with one simple call.
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's 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;
};
});
If you include that snippet, you can implement your solution like 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");
Your MODULE now has the following callable methods:
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 */);
Where event is a space-delimited list of events, handler is your callback, and data is an optional value to pass to your callbacks.
You can refer to jQuery's documentation for more details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With