If you didn’t know already, its very important to always clone any custom events you create. Otherwise, when redispatching an event, it won’t be typed correctly and will use the default Event class’ properties. Meaning any data or event type you might’ve been passing along will be lost in the redispatch.
Another slight annoyance however is that event.target is overwritten when an event is redispatched. As far as I can tell, there’s no way around this.
For instance, I might have a custom class (MyDispatcher) dispatching a custom event (CustomEvent) to its parent (FirstListener), where it needs to know some property of the original dispatcher. But perhaps its parent (SecondListener) also needs the same event. I’ll typically just redispatch the event. But what you’ll find is that event.target will always be the class that has done the last dispatch, regardless of who originally dispatched the event, so in the case of the root parent, SecondListener, event.target will be FirstListener, not MyDispatcher. Sure you still have any data relevant to the event and can create as many properties as you might need in the custom event, but that seems rather bothersome to me if there’s alot of properties to access in the original dispatcher.
As a workaround, I start with a single, generic property in my custom class that can take any data type (_data:* = null). I then pass into that the this keyword when I first dipsatch the event, taking with it the entire instance of the original dispatcher – as long as the original dispatcher isn’t a huge memory beast.
The benefit here is instead of using event.target I can always use event.data and know that I’m getting all of the public properties of the original dispatcher. Its also correctly typed, even if you haven’t imported the dispatcher’s class.
public class CustomEvent extends Event {
import flash.events.Event;
private static const MY_EVENT:String = "myEvent";
private var _data:*;
public function CustomEvent(type:String,data:*=null) {
_data = data;
super(type,data);
}
public override function clone():Event {
return new CustomEvent(type,data);
}
public function get data():* {
return _data;
}
}
public class MyDispatcher extends Sprite {
import flash.display.Sprite;
import CustomEvent;
private var myVar:String = "some public property";
public function MyDispatcher() {
}
public function sendEvent():void {
dispatchEvent(new CustomEvent(CustomEvent.MY_EVENT,this));
}
public function get myVar():String {
return myVar;
}
}
public class FirstListener extends Sprite {
import flash.display.Sprite;
import MyDispatcher;
import CustomEvent;
public function FirstListener() {
var myDispatcher:MyDispatcher = new MyDispatcher();
myDispatcher.name = "myDispatcher";
myDispatcher.addEventListener(CustomEvent.MY_EVENT,myEventHandler,false,0,true);
}
public function init():void {
myDispatcher.sendEvent();
}
private function myEventHandler(evt:CustomEvent):void {
trace(this.name,"received an event");
trace("evt.target.name is ",evt.target.name); // is MyDispatcher
trace("evt.data.name is ",evt.data.name); // is MyDispatcher
dispatchEvent(evt);
}
}
public class SecondListener extends Sprite {
import flash.display.Sprite;
import CustomEvent;
public function SecondListener() {
var firstListener:FirstListener = new FirstListener();
firstListener.name = "firstListener";
firstListener.addEventListener(CustomEvent.MY_EVENT,myEventHandler,false,0,true);
firstListener.init();
}
private function myEventHandler(evt:CustomEvent):void {
trace(this.name,"received an event");
trace("evt.target.name is ",evt.target.name); // is NOT MyDispatcher, but FirstDispatcher instead
trace("evt.data.name is ",evt.data.name); // is MyDispatcher
}
}
Have a question or comment?