It might be helpful to understand how Flash Player handles events. Whenever an event occurs, Flash Player dispatches an event. If the event target is not a visible element on the screen, Flash Player can dispatch the event object directly to the designated target. For example, Flash Player dispatches the result event directly to an HTTPService component. However, if the target is a visible element on the screen, Flash Player dispatches the event and it travels from the outermost container (the Application container), down through the target component, and then back up to the Application container. Event flow is a description of how that event object travels through an application. As you have seen by now, Flex applications are structured in a parent-child hierarchy, with the Application container being the top-level parent. Earlier in this lesson, you saw that flash.events.EventDispatcher is the superclass for all components in Flex. This means that every object in Flex can use events and participate in the event flow; they can all listen for an event with the addEventListener() method, but will hear the event only if the listening object is part of the event flow. When an event occurs, an event object makes a round trip from the root application, through each of the containers on the way to the component that was responsible for the event (known as the target of the event). For example, if a user clicks a Button named button, Flash Player will dispatch an event object whose target is button. Although the target of an event is constant throughout the flow, an event object also has a currentTarget property, which indicates which element in the flow currently has the event object. The event flow is conceptually divided into three parts:
The following image describes a branch of an application, in which a Button is contained within an HBox, which is contained by a Panel, which sits in the root Application. For the context of this example, other elements in the application are moot. If a user clicks the Button, Flash Player dispatches an event object into the event flow. The object's journey starts at the Application, moves down to the Panel, moves to the HBox and finally gets to the Button. The event object then "bubbles" back up to Application, moving again through the HBox and Panel on its way up. In this example, the capture phase includes the Application, Panel and HBox during the initial downward journey. The target phase comprises the time spent at the Button. The bubbling phase comprises the HBox, Panel, and then Application containers as they are encountered during the return trip. This event flow offers far more power and flexibility to programmers than the event model of previous versions of ActionScript. Prior to Flex 2, event listeners had to be assigned directly to the object that generated an event. In Flex 2, you can still do this or you can register event listeners on any node along the event flow. All instances of the Event class have a bubbles property that indicates whether that event object will participate in the bubbling phase of the event flow. You can look to the API documentation to find out whether a particular event type will bubble. In practicality, this means that an event can occur in a child component and be heard in a parent. Consider this simple example: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" click="showAlert(event)" > <mx:Script> import mx.controls.Alert; private function showAlert(event:Event){ var msg:String = event.target.toString() +" clicked"; Alert.show(msg); } </mx:Script> <mx:Panel click="showAlert(event)" > <mx:HBox click="showAlert(event)" > <mx:Button click="showAlert(event)"/> </mx:HBox> </mx:Panel> </mx:Application> In this case, there is a Button control inside an HBox, inside a Panel, inside an Application. When the button is clicked, the click event of the Button control is heard from the event handler of the Button, HBox control, Panel, and Application, and as such, four Alert boxes pop up, all saying the following: Application4.panel:Panel.hbox:HBox.button:Button clicked The click event of the Button control can be captured at the Button control itself or in any of the parent containers of the Button instance. This happens because click is a bubbling event. The bubbles property of the Event class is Boolean, which indicates whether an event should bubble. By default, bubbles is set to false on newly created events (although it is preset to TRue for some built-in events, such as click). When you create event instances or event subclass instances, you can decide whether you want to enable bubbling for the event. If you leave the bubbling to the default false value, the event can be captured only at the source of the event (the Button control in the preceding example). However, if it is set to true, it can be captured by a parent of the dispatching component (such as the HBox, Panel and Application). In the EComm application, when the itemAdded event is dispatched from the GroceryDetail component, currently you are capturing the event in FoodList and then redispatching it. However, if the ProductEvent could optionally be set to bubble, there would be no need for the FoodList to capture and rebroadcast the eventit could be handled directly in the EComm application.
|