views:

1217

answers:

3

Hi just wondering if it is possible to take advantage of event bubbling in non display list classes in AS3.

For example in the model of an application where there is a City class that contains many Cars. What methods are there to attach an event listener to a City object and receive events that bubble up from the child Cars. To clarify The City and Car objects are not part of the display list, they are not DisplayObjects. So can bubbling be implemented outside of the display list somehow?

As far as I know, this is not possible without manually attaching event listeners to each Car object and re dispatching the event from the City object. Anyone else have a cleaner solution?

+1  A: 

I'm not sure I am fully understanding, but when you create an event you can say that it bubbles and so when it dispatches it will bubble.

http://livedocs.adobe.com/flex/3/html/help.html?content=createevents_3.html

http://livedocs.adobe.com/flex/3/langref/flash/events/Event.html#Event()

I believe that would allow you to attach an event listener to your city for the right types of events and that would catch events thrown by cars. I haven't ever tried this though so I am not sure.

update:

Ah, I didn't realize this. You are correct. From the following link:

http://livedocs.adobe.com/flex/3/html/help.html?content=events_08.html

Capturing and bubbling happen as the Event object moves from node to node in the display list: parent-to-child for capturing and child-to-parent for bubbling. This process has nothing to do with the inheritance hierarchy. Only DisplayObject objects (visual objects such as containers and controls) can have a capturing phase and a bubbling phase in addition to the targeting phase.

The only way I can see around this would be for you to register the child with the parent (the car with the city) every time a new one is added as a child. At that point you could add an event listener in the parent (city) and then re-dispatch an event from the parent (city) any time a event is handled from the child (car). Its ugly I know, and you would want to make sure you remove the event listener anytime that you remove a child, but it's the only real solution I can see.

Ryan Guill
It bubbles, but only in the DisplayList, so only if it's dispatched from a DisplayObject, so then the event knows the children and parents of its current node, and so can travel up and down the tree. My imaginary City object is not part of the DisplayList.
Brian Heylin
You're right, sorry about that. updated my answer with a possible solution, see what you think.
Ryan Guill
Cools thanks Ryan, that's my clumsy solution too, I was hoping that there was maybe some sort of IBubbleTree interface that my model could implement and insert itself into a bubbling system. Although, now that I say it I could write that system myself for a generalized tree of IEventDispatchers.hmmm
Brian Heylin
A: 

I'm not sure what year this was posted, but I just discovered this and boy is it stupid. Why would bubbling be dependent on the display list? It seems to me that in building the Event model in AS3, Adobe should have implemented bubbling for any Classes. I need to pass data between disparate classes much more often than I need to make multiple display objects listen to each other. Not to mention it is much easier to reference display objects with the display list and root than it is to reference a dynamic instance used by a dynamic instance used by a dynamic instance (you get it). AS2's event model isn't that far away from what AS3's event model is after all

Well yes, I find that bubbling is quite handy in the display list and I would like to utilize it in the model of an application too. But to satisfy this, your model classes would need to implement some sort of ITree or IHasParent interface system so that bubbling can take place automatically.
Brian Heylin
+1  A: 

This class was my solution to that problem. Basically have your classes that would normally extend EventDispatcher instead extend BubblingEventDispatcher

and then call the addChildTarget( target:BubblingEventDispatcher ) function to setup children that you can catch bubbled events from.

This solution uses a sprite for each event dispatcher, but results in only 1 byte of extra memory usage per class

package 
{
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.events.EventDispatcher;

 public class BubblingEventDispatcher extends EventDispatcher
 {
  //We have to use a sprite to take advantage of flash's internal event bubbling system
  private var sprite:Sprite;

  public function BubblingEventDispatcher()
  {
   //initialize our sprite
   sprite = new Sprite();
  }

  public override function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
  {
   sprite.addEventListener( type, listener, useCapture, priority, useWeakReference );
  }

  public override function dispatchEvent(event:Event):Boolean
  {
   return sprite.dispatchEvent( event );
  }

  //We must add child targets if we want to take advantage of the bubbling
  public function addChildTarget( target:BubblingEventDispatcher ):void
  {
   sprite.addChild( target.eventTarget as Sprite );
  }

  public function get eventTarget():EventDispatcher
  {
   return sprite;
  }
 }
}
whuffaKilla
Thanks for the response. I'm trying to move over to as3-signals at the moment, they also have a bubbling solution. This looks like it does the job for native Events. Nice work ;)
Brian Heylin