Can you help me understand event dispatching? Yes, I think I Can!

What a week this has been so far. The in-house legal counsel of tracfone gave me a call regarding a posting on this blog. Someone posted the personal number of tracfone's CEO in comments to another post. They wanted me to remove it. Cindy (Tracfone lawyer) was rather nice about it. She said it was the first time she's done something other than send a cease and desist. After discussing the issue w/ my lawyer, we decided it was okay for me to remove the comments. That along with water stains on the ceiling and a leaky gas stove prevented me from posting earlier in the week. It's been a week worth living for.

Today I want to talk about event dispatching in Flex. Coming from a web (and ColdFusion) based background, dealing with events and listeners tends to be a bit of a mystery.

Two people asked me questions about events lately. One was Chris, a frequent reader of this blog. His question was simply "Can you help me understand event dispatching". Additionally, my good friend Critter asked me a question about itemRenders in Flex . The answer there was also to use events, but at the time I was too busy to give Critter a more in depth answer. I thought I'd try to address both questions in one swoop.

There is some terminology you need to understand regarding events:

  • Event: An event is the process of some action happening. In 'old' HTML development, the only event that really occurred was a form submit or a link click. Because each action told the server something happened. With AJAX (JavaScript), you can use a web page to respond to a lot more events than just a button click. In Flex, events abound all over the place; it could be a button click; or typing something on the keyboard or it a video started playing. Events are what makes Flex tick.
  • Broadcast: I wasn't sure whether to call this one broadcast or dispatch. Events are broadcast using an event dispatcher. Broadcastig means that you tell the world (AKA other object) that Basically, this means that something (an event) happened.
  • Listener: There is more to using events than telling other objects that something happened. That other object has to be listening for it. When the event is broadcast, the listener tells the 'parent' object to do something.
  • Bubble: Within Flex, by default, events only broadcast themselves to their parent component. If you want the event to broadcast to its parent's parent (and all the way up your component chain), then you tell that event to bubble. Think of it as a balloon filled with helium, floating up to the top of a gymnasium. The ceiling is your top level component (Application) and it could pass any number of other components along the way.

That is the terminology you should be familiar with in regards to events. I'm going to take a simplified version of Critter's code (since it's already public) and use it to demonstrate how events work.

I'm going to do this from the inside out and first examine the itemRenderer, timeline.mxml in Critters example:

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" verticalGap="0">
<mx:Script>
<![CDATA[
public function testEvent():void{
dispatchEvent(new Event('test',true));
}
]]>
</mx:Script>

<mx:Button label="Button" click="testEvent()" />
<mx:VBox width="100%" height="100%" verticalGap="0" verticalScrollPolicy="off">
<mx:Label text="{data.value}" fontSize="9" />
</mx:VBox>
</mx:HBox>

I changed the image to a button (because I didn't have the image source). I also simplified the two text and labels into a single label. The passed in data is turned into 'data.value', instead of the more advanced objects that Critter is clearly using.

The top of the itemrenderer contains a function to broadcast an event, creatively named 'test'. The 'true' value after the name 'test' in the Event Constructor tells Flex to bubble the event. When using itemRenderer, you usually want to bubble it.

This is the main.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
      
public function init():void{
myTileList.addEventListener('test',listen);
}
   
[Bindable] public var myList : ArrayCollection = new ArrayCollection([
{value:"test 1"},
{value:"test 2"},
{value:"test 3"},
]);

public function listen(e:Event):void{
trace('event happened');
}
]]>
</mx:Script>

<mx:TileList itemRenderer="Timeline" dataProvider="{myList}" id="myTileList" />

</mx:Application>

The application tag starts the file, and calls the init method on creationComplete. The init method adds an event listener. It says "Whenever the Tile List broadcasts the event 'test', call the function listen.

The listen function just uses trace to prove to us that the event did occur.

Our data provider is an ArrayCollection with 3 items in it. The tile list will display all 3 items.

So, compile the app, run it [in debug mode] and you'll see the item renderer displaying all 3 items. Click one of the buttons and you should see the 'event happened' text roll across the console.

So, I've described event dispatching in its basic form. There are a few more things you might find interesting when dealing with events.

You can make an event show up in MXML code hinting using metadata, something like this:

<mx:metadata>
[Event(name="test", type="flash.events.Event")]
</mx:metadata>

In ActionScript classes, the metadata definition for events goes between the package definition and the class definition.

Many events you deal with will need to pass custom data back and forth. You can easily create your own class, extending the event class, with custom properties. You can dispatch your own custom events using the same method I used here.

Often instead of hand coding the event name, 'test' in this case, that name will often be stored in a static constant as part of the custom event class. This is very common in the Flex Framework. For example the DragEvent's DRAG_COMPLETE constant.

If two events do different things, but need similar data, combine them into one custom event class. The Flex To use DragEvent again, it handles DRAG_COMPLETE, DRAG_OVER, DRAG_START and numerous other drag related events.

The precipitation outside sounds like hail; and we're still getting thunder. I think I think it's time to step away and go to bed!

Note: I borrowed the image from Here

Related Blog Entries

Comments
All Content Copyright 2005, 2006, 2007 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.8.