Good stuff, a couple months back I posted my very lightweight EventPublisher
class, along with a quick example.
http://threebit.net/mail-archive/rails-spinoffs/msg00548.html
...and here is the code...
///// EventPublisher Class
/////////////////////////////////////////////////////////
//
// The EventPublisher class allows objects to fire events (and other objects
to
// subscribe handlers to those events). The events can be fired either
// synchronously or asynchonously (depending on how the handlers register
themselves),
// and may pass optional arguments to the handlers.
EventPublisher = Class.create();
EventPublisher.prototype = {
initialize: function() {
},
// pass the asynch flag (true/false) as the 3rd argument, or omit it to
default to false
attachEventHandler: function(eventName, handler) {
// using an event cache array to track all handlers for proper
cleanup
if (this.allEvents == null)
this.allEvents = new Array();
// loop through the event cache to prevent adding duplicates
var len = this.allEvents.length;
var foundEvent = false;
for (var i = 0; i < len; i++) {
if (this.allEvents[i] == eventName) {
foundEvent = true;
break;
}
}
if (!foundEvent)
this.allEvents.push(eventName);
eventName = eventName + "_evt"; // appending _evt to event
name to
avoid collisions
if (this[eventName] == null)
this[eventName] = new Array();
//create a custom object containing the handler method and the
asynch flag
var asynchVar = arguments.length > 2 ? arguments[1] : false;
var handlerObj = {
method: handler,
asynch: asynchVar
};
this[eventName].push(handlerObj);
},
// Removes a single handler from a specific event
removeEventHandler: function(eventName, handler) {
eventName = eventName + "_evt"; // appending _evt to event
name to
avoid collisions
if (this[eventName] != null)
this[eventName] = this[eventName].reject(function(obj) { return
obj.method == handler; });
},
// Removes all handlers from a single event
clearEventHandlers: function(eventName) {
eventName = eventName + "_evt"; // appending _evt to event
name to
avoid collisions
this[eventName] = null;
},
// Removes all handlers from ALL events
clearAllEventHandlers: function() {
if (this.allEvents) {
var len = this.allEvents.length;
for (var i = 0; i < len; i++) {
this.clearEventHandlers(this.allEvents[i]);
}
}
},
//to pass arguments to the handlers, include a 2nd argument (anonymous
object that can contain whatever you want)
fireEvent: function(eventName) {
var evtName = eventName + "_evt"; // appending _evt to event
name to
avoid collisions
if (this[evtName] != null) {
var len = this[evtName].length; //optimization
for (var i = 0; i < len; i++)
{
try
{
if (arguments.length > 1)
{
if (this[evtName][i].asynch)
{
var eventArgs = arguments[1];
var method = this[evtName][i].method.bind(this);
setTimeout(function() { method(eventArgs)
}.bind(this), 10);
}
else
this[evtName][i].method(arguments[1]);
} else {
if (this[evtName][i].asynch)
{
var eventHandler = this[evtName][i].method;
setTimeout(eventHandler, 1);
}
else
if (this && this[evtName] &&
this[evtName][i] &&
this[evtName][i].method)
this[evtName][i].method();
}
}
catch (e) {
if (this.id) {
alert("error: error in " + this.id +
".fireevent():\n\nevent name: " + eventName + "\n\nerror message:
" +
e.message);
} else {
alert("error: error in [unknown
object].fireevent():\n\nevent name: " + eventName + "\n\nerror
message: " +
e.message);
}
}
}
}
}
};
On 7/21/06, TJ Stankus <tj-vv4rFJV6HEI@public.gmane.org>
wrote:>
> Good stuff. I''m really looking forward to digging through this.
>
> -TJ
>
> On 7/21/06, Seth Dillingham
<seth.dillingham-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> > Hey all,
> >
> > A couple months ago I was working on a pretty complex app that uses
> > Prototype.js very heavily. In the process I came up with a way to use
> > Prototype to produce custom events, reliably, in javascript.
> >
> > By "custom events" I mean stuff like "message
received" and "results
> > available" and "progress update", not browser events
like click and
> > mouseover.
> >
> > I showed it to Sam (you know, *THE Sam*, our Sam) at RubyConf last
> > month, and he got pretty excited. We skipped one of the sessions, sat
> > down in the lobby, and went over the whole thing for an hour. He liked
> > it. I''ve even received ONE WHOLE EMAIL from him on the topic,
since
> > then. ;-)
> >
> > The JS events stuff have been extracted from the project so they can
> > be used by others (people or projects).
> >
> > ** It''s all written up in a longish article (long because of
the
> > sample code), here:
> > <http://www.truerwords.net/articles/web-tech/custom_events.html>
**
> >
> > There are links on the page to a useless demo app, and all of the
actual
> code.
> >
> > Let me warn you that there''s a lot there, BUT you
don''t need all of it
> > if you want to play with it! I included an "even tracing"
module to
> > help with debugging, and an optional event broker (which is explained
> > in the article). The most important parts are all in one file, and are
> > only about 4 kb.
> >
> > The basic idea is that you have event publishers and event subscribers
> > (listeners). Any class or object in your app can be either or both.
> > Listeners subscribe to publishers for the events they want to receive,
> > publishers remain ignorant of who is listening.
> >
> > If you mix in an Event Broker class as well, then the listeners
don''t
> > even need to know about the event publishers... they just tell the
> > broker that they care about all events of a particular type, and
> > they''ll receive them regardless of which publisher produced
it. (This
> > is handy in cases where you have a large collection of publishers, or
> > when you may not know what objects have been included on the page.)
> >
> > OK, this is more than long winded enough. It''s all explained
in the
> article.
> >
> > Seth
> >
> > P.S. This custom events code is a pretty thorough solution... so yes,
> > I realize it''s not for everyone, but I thought it might be
useful for
> > some people on the list. At least it''s "on-topic"!
> > _______________________________________________
> > Rails-spinoffs mailing list
> > Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
> > http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs
> >
> _______________________________________________
> Rails-spinoffs mailing list
> Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
> http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs
>
_______________________________________________
Rails-spinoffs mailing list
Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs