Pages

August 22, 2009

Creating a Custom Event

Posted by Jeremy Mitchell
Flex applications consist of a component hierarchy starting with the Application root. Components are built-in or custom.



Interaction between components may occur down the component hierarchy (parent to child) or up (child to parent).

When a parent component interacts with a child component, the parent utilizes the child component's interface (API). This interface includes the component's public properties and methods.

For example, a parent component may hide a child component by setting its visible property to false.
<!-- parent component -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
        <![CDATA[
            private function doSomething(event:MouseEvent):void {
                lbl.visible = false; // parent (Application) interacting with child (Label)
            }
        ]]>
    </mx:Script>
    <!-- child component -->
    <mx:Label id="lbl" text="Hello there"/> 
    
    <!-- child component -->
    <mx:Button label="Hide Label" click="doSomething(event)"/>
    
</mx:Application>
Note: The Label's visible property is actually marked private but is publicly exposed through an implicit getter and setter.
Conversely, when a component wants to interact with a parent (or ancestor) component, it does so by dispatching events. Events are dispatched to signify an occurrence has taken place and include the details of the occurrence wrapped inside an event object.

Components may express an interest in a particular event by registering an event listener. Event listeners map an event to a method. This method is referred to as an event handler and is designed to perform one or more actions in response to an event.

Because an event (built-in or custom) propagates down through the display hierarchy during the Capturing phase of the event flow and back up during the Bubbling phase, ancestor components have two opportunities to register event listeners.

Note: Events do not bubble by default. All events extend the flash.events.Event class which requires 3 constructor arguments (type, bubbles and cancelable). Set bubbles to true and override the clone method to activate event bubbling.
In addition to the details of the event (target, currentTarget, type, eventPhase, etc), custom event objects can carry a "payload" used to transfer data. The payload is nothing more than a storage variable declared as a property of the event object.

In this short video, I will create a custom event designed to carry user information (username / password) captured when the user logs in.



Correction: In the video, I failed to override the clone method. Without overriding the clone method, a custom event will not be capable of bubbling.
View the source code of the custom event example.

After watching the video, it may still not be obvious why this approach is considered a best practice. Following the principles of encapsulation, we want our components to represent a "black box". We interact with a component via its public interface (API) and it broadcasts information about itself using events. If you find the event and the information it contains to be interesting, listen for the event and act on it.

Interaction between components in this fashion promotes loose coupling which ultimately provides greater flexibility.