Something I thought should work but had trouble figuring out was just revealed to me today. Say i have a couple of 'nested' objects, but they're NOT display objects, and I want to 'bubble' the event up through the parents. Of course conceptually real bubbling will work in this situation if the parents were display objects, but if they're not it's still possible without too much code.
Here's the example of what we want to work, made up of classes MyClassA and MyClassB and event class MyEvent:
class MyClassA {
private var b:MyClassB;
public function MyClassA():void{
this.b = new MyClassB();
this.addEventListener(MyEvent.START, relayEvent);
this.addEventListener(MyEvent.PROGRESS, relayEvent);
this.addEventListener(MyEvent.FINISH, relayEvent);
}
public function start():void {
this.b.start();
}
private function relayEvent(event:MyEvent):void {
//relay same event.
dispatchEvent(event);
}
}
class MyClassB {
public function MyClassB():void{
}
public function start():void {
var event:MyEvent = new MyEvent(MyEvent.START);
dispatchEvent(event);
}
}
class MyEvent extends Event{
public const START:String = "start";
public const PROGRESS:String = "progress";
public const FINISH:String = "finish";
public class MyEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false ) {
super(type,bubbles, cancelable);
}
}
In the above we're trying to expose several of MyClassB's events (which could be of different event class types) to observers of MyClassA, whom we do not want to have to know about MyClassB.
In your observing class picture the following:
class MyObserver {
public function MyObserver():void {
var myObjA:MyClassA = new MyClassA();
myObjA.addEventListener(MyEvent.START, onStart);
myObjA.start();
}
private function onStart(event:MyEvent):void {
//do something useful
}
}
The problem is, that when you run this you'll get a type coersion error at MyObserver#onStart in relayEvent. This is because the MyEvent object in MyClassA#relayEvent gets changed from type MyEvent to Event.
The solution is to create clone methods in each of your custom event classes that duplicate the class and return the same type. Behind the scenes, the Flash Player is calling clone, but since it doesnt' exist, it calls the super (Event#clone()) which returns its own type, Event. Here's my custom event class again with the clone method:
class MyEvent extends Event{
public const START:String = "start";
public const PROGRESS:String = "progress";
public const FINISH:String = "finish";
public class MyEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false ) {
super(type,bubbles, cancelable);
}
public function clone():MyEvent {
var clone:MyEvent = new MyEvent(this.type, this.bubbles, this.cancelable);
return clone;
}
}