Manually triggering event listener functions

ActionScript 3.0 was designed to provide much better error handling than its precessor, with both run-time and compile-time checks being made. Yet although the language is stricter in some senses, it also provides new, considerable, flexibility. For example:

  1. The rest... parameter, which enables a function to receive any number of comma-delimited arguments.
  2. The ability to set default parameters for function arguments.

These two features can prove to be extremely useful.

Another place where you run into ActionScript 3.0’s pedantry is in dealing with event handlers. Event handlers must be declared such that they are equipped to (naturally) handle an event. For example:

private function init(e:Event):void
{
  fadeIn();
  trace(this + "initialised");
}

We tend to trigger init methods when an object is added to the display list. So we subscribe the listener function as follows inside our constructor function:

addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);

This is all well and good, and if the listener is triggered without a valid Event object being sent to it, Flash will produce an error (part of the strict error checking). But what if, occasionally, we did want to trigger a function which is configured to be an event handler, but trigger it manually (i.e. not on the generation of an event)?

We have the required e:Event parameter to deal with. (Not also, incidentally, that all other Event object types extend the base Event type, so you can get away with typing the required object simply as Event, for flexibility.)

We have a number options here. One is to use the event listener as a merely a proxy when we define it, so it in turn calls another function:

private function initListener(e:Event):void
{
  init();
}

private function init():void
{
  fadeIn();
  trace(this + "initialised");
}
...
addEventListener(Event.ADDED_TO_STAGE, initListener, false, 0, true);
...

This leaves us free to call the init() method whenever we want then – it would not have to be (or be able to be) triggered on an event’s dispatch. This is fine, however it seems rather verbose. It means we have to write, theoretically, twice as meny functions!

Another option is we can send a “dummy” event to our listener method whenever we want to manually call it:

private function init(e:Event):void
{
  fadeIn();
  trace(this + "initialised");
}
...
init(new Event(Event.ADDED_TO_STAGE));

This works, but it seems messy to be faking events.

The third option takes us back to the beginning of this article, and the topic of default values for function parameters:

private function init(e:Event = null):void
{
  fadeIn();
  trace(this + "initialised");
}
...
init(new Event(Event.ADDED_TO_STAGE));

Because it is possible to supply default values, we can avoid an argument mismatch error but specifying that if no event object is actually sent to the listener, that parameter should be defined as null.

While some may say this violates AS3’s tight security, it is currently our preferred solution to this issue. You might find it the best way to go too. Remember that inside the body of the event handler you can always check to see if event parameter “e” is defined and, if so, what kind of event it is. You can also surround certain attempts by try... catch... finally clauses to avoid your whole application breaking.

We always define event handlers with the event parameter set to null, and – of course – we add them with weak references.

Add a comment:

*