Video icon 64
Learn to Code. Start your free trial today.
Advertisement

AS3 101: Quick Tip - Dispatching Events Without Extending EventDispatcher

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →
This post is part of a series called AS3 101.
AS3 101: Events - Basix

It's rare, but it happens. Sometimes you absolutely need to extend a class, and that class does not already extend EventDispatcher. At the same time, you absolutely need your class to be an EventDispatcher. Because ActionScript 3 does not allow multiple inheritance, how do you reconcile this?

In other situations, perhaps you would like to create a class that has a bunch of static methods on it, and isn't really meant to be instantiated. You would like to be able dispatch events from this class as well, but you can extend EventDispatcher because that enables instance methods, not class methods.

Let's take a look at how to achieve these goals.


Step 1: How To Do It

The solution in both cases is to instantiate, hang onto, and use an EventDispatcher object. That is, a new EventDispatcher() object, not necessarily any of its subclasses. In the case of needing to extend something else, you can also have your class implement the IEventDispatcher interface.

The process goes something like this:

  1. Implement IEventDispatcher (not for the static class).

    package {
        import flash.events.*;
        public class ArrayDispatcher extends Array implements IEventDispatcher {
            public function ArrayDispatcher() {
            }
        }
    }
  2. Create a new EventDispatcher object, and store it in a property.

    private var _dispatcher:EventDispatcher
    public function ArrayDispatcher() {
        _dispatcher = new EventDispatcher();
    }
  3. Implement the methods defined by IEventDispatcher, and simply wrap around the matching method on your EventDispatcher instance.

    public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void {
        _dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
    }
    public function dispatchEvent(event:Event):Boolean {
        return _dispatcher.dispatchEvent(event);
    }
    public function hasEventListener(type:String):Boolean {
        return _dispatcher.hasEventListener(type);
    }
    public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void {
        _dispatcher.removeEventListener(type, listener, useCapture);
    }
    public function willTrigger(type:String):Boolean {
        return _dispatcher.willTrigger(type);
    }

Step 2: A Static EventDispatcher

For reference, implementing this in a static class might look like this:

package {

    import flash.events.*;

    public class StaticDispatcher {

        private static var _dispatcher:EventDispatcher = new EventDispatcher();

        public static function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void {
            _dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
        }
        public static function dispatchEvent(event:Event):Boolean {
            return _dispatcher.dispatchEvent(event);
        }
        public static function hasEventListener(type:String):Boolean {
            return _dispatcher.hasEventListener(type);
        }
        public static function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void {
            _dispatcher.removeEventListener(type, listener, useCapture);
        }
        public static function willTrigger(type:String):Boolean {
            return _dispatcher.willTrigger(type);
        }
    }
}

Note that there is no extends or implements, all members are now static, and the _dispatcher property is now created directly on the property, instead of in the constructor (because there is no constructor).


That's All

Although quick to explain, this is definitely an advanced technique, and you probably won't require it if you're at a point where dispatching your own events is still a new concept. But file this away somewhere in your mind so you can come back to this example when you need it.

Advertisement