增加移除事件之深究 Dig into added/addedToStage/removed/removedFromStage events

Events added, addedToStage, removed and removedFromStage offer a great opportunity for performing initialization and cleaning up. Here, I refer the four types of events as display list events. The basic information on display list events can be found in Flex API. However, the API does not have answers for following questions:

  • Exactly when will they occur?
  • in want order (for nested components)?

We try to find the answers with the following experiment:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="onCreationComplete();">

    <mx:Button id="control" label="Remove" toggle="true" selected="false" click="toggleAddRemove();"/>
    <mx:Panel width="400" height="120" layout="absolute" id="form">
        <mx:HBox width="100%" height="50%" id="box">
            <mx:Button label="Button" id="button"/>
        </mx:HBox>
    </mx:Panel>
</mx:Application>

When the top button is clicked, it toggles to remove/add the form from/to the application.

flexadd

Register listeners:

private function onCreationComplete():void {
    box.addEventListener(Event.ADDED, onEvent);
    box.addEventListener(Event.ADDED_TO_STAGE, onEvent);
    form.addEventListener(Event.ADDED, onEvent);
    form.addEventListener(Event.ADDED_TO_STAGE, onEvent);
    button.addEventListener(Event.ADDED, onEvent);
    button.addEventListener(Event.ADDED_TO_STAGE, onEvent);
    box.addEventListener(Event.REMOVED, onEvent);
    box.addEventListener(Event.REMOVED_FROM_STAGE, onEvent);
    form.addEventListener(Event.REMOVED, onEvent);
    form.addEventListener(Event.REMOVED_FROM_STAGE, onEvent);
    button.addEventListener(Event.REMOVED, onEvent);
    button.addEventListener(Event.REMOVED_FROM_STAGE, onEvent);
}

private function onEvent(event:Event):void {
    trace(event.target + "\t" + event.type);
}

Below is the list of events fired:

// initial

TestRemove0.form    addedToStage
TestRemove0.form.box    addedToStage
TestRemove0.form.box.button    addedToStage

// top button is clicked to remove the form

TestRemove0.form    removed
TestRemove0.form    removedFromStage
TestRemove0.form.box    removedFromStage
TestRemove0.form.box.button    removedFromStage

// top button is clicked to add the form back

TestRemove0.form.border    removed
TestRemove0.form.border    added
TestRemove0.form.UIComponent11.TitleBackground18    removed
TestRemove0.form.UIComponent11.TitleBackground35    added

TestRemove0.form    added
TestRemove0.form    addedToStage
TestRemove0.form.box    addedToStage
TestRemove0.form.box.button    addedToStage
TestRemove0.form.box.button.upSkin    removed
TestRemove0.form.box.button.upSkin    removed
TestRemove0.form.box.button.upSkin    removed
TestRemove0.form.box.button.upSkin    added
TestRemove0.form.box.button.upSkin    added
TestRemove0.form.box.button.upSkin    added

// top button is clicked to remove the form again

TestRemove0.form    removed
TestRemove0.form    removedFromStage
TestRemove0.form.box    removedFromStage
TestRemove0.form.box.button    removedFromStage

Jack's conclusions

  • When a component is added to the stage (i.e., added to any container in the stage's display list), an added event will be dispatched for this component, followed by an addedToStage event. Next, if this component is a container, it's descendants will fire addedToStage in branch-to-leaf order.
     
  • When a component is removed from the stage (i.e., removed from any container in the stage's display list), a removed event will be dispatched for this component, followed by an removedFromStage event. Next, if this component is a container, it's descendants will fire removedFromStage in branch-to-leaf order.
     
  • Occasionally, a component's skin may fire added/removed events for the component. You might need to check the event target.