Friday, March 15, 2013

AS3: event.stopImmediatePropagation() v.s. event.stopPropagation()

When you are working on a flash/flex project and there's multiple layers inside the project, there ought to be changes where you have multiple places listening for the same Events. Luckily for us, there are ways to stop the Events from dispatching upwards. However there seems to be 2 different methods to stop it and what's the difference between the 2 methods event.stopImmediatePropagation() and event.stopPropagation()? I have created a simple demo to show you the differences between both methods.

Source code of the Main Application file - stopBubbleEventTest.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" 
    minWidth="955" minHeight="600" 
    xmlns:Comp="*" creationComplete="creationCompleteEvent(event)" 
    name="stage">
 <!-- Styling the VBox -->
 <mx:Style>
  VBox{
   paddingLeft:10;
   paddingRight:10;
   backgroundAlpha:0.2;
   backgroundColor:#00FF00;
  }
 </mx:Style>
 <mx:Script>
  <![CDATA[
   import mx.events.FlexEvent;
   
   //Upone creation complete of this mxml files
   protected function creationCompleteEvent(event:FlexEvent):void
   {
    //Add an Event Listener to the button / 
    //Upon clicking on the button, run the actions in clickEvent function
    btnClick.addEventListener(MouseEvent.CLICK, clickEvent);
    //Change the state of the checkbox of the highest level
    stageControls.chkOption.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
   }
   
   private function clickEvent(event:Event):void{
    //Reset all the values in the textfields
    stageControls.txtResult.text = "";
    level0Controls.txtResult.text = "";
    level1Controls.txtResult.text = "";
    level2Controls.txtResult.text = "";
    level3Controls.txtResult.text = "";
    level4Controls.txtResult.text = "";
    stageControls.txtResult2.text = "";
    level0Controls.txtResult2.text = "";
    level1Controls.txtResult2.text = "";
    level2Controls.txtResult2.text = "";
    level3Controls.txtResult2.text = "";
    level4Controls.txtResult2.text = "";
    //Dispatch an event that will bubble / move all the way to the highest level
    btnClick.dispatchEvent(new DataEvent(DataEvent.DATA,true,false,"Click"));
   }
   
  ]]>
 </mx:Script>
 <mx:HBox width="100%" horizontalAlign="center">
  <mx:CheckBox id="chkEventType" selected="false"
      label="Are we using event.stopImmediatePropagation()?"/>
 </mx:HBox>
 <Comp:FormControls id="stageControls" 
        useImmediate="{chkEventType.selected}"
        top="30"/>
 <mx:VBox name="level0" width="100%" height="100%" verticalGap="0" top="80">
  <Comp:FormControls id="level0Controls"
         useImmediate="{chkEventType.selected}"/>
  <mx:VBox name="level1" width="100%" height="100%" verticalGap="0">
   <Comp:FormControls id="level1Controls"
          useImmediate="{chkEventType.selected}"/>
   <mx:VBox name="level2" width="100%" height="100%" verticalGap="0">
    <Comp:FormControls id="level2Controls"
           useImmediate="{chkEventType.selected}"/>
    <mx:VBox name="level3" width="100%" height="100%" verticalGap="0">
     <Comp:FormControls id="level3Controls"
            useImmediate="{chkEventType.selected}"/>
     <mx:VBox name="level4" width="100%" height="100%" verticalGap="0">
      <Comp:FormControls id="level4Controls"
             useImmediate="{chkEventType.selected}"/>
      <mx:Button id="btnClick" label="Click me..."/>
     </mx:VBox>
    </mx:VBox>
   </mx:VBox>
  </mx:VBox>
 </mx:VBox>
</mx:Application>
SOurce code of my custom component - FormControls.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" creationComplete="creationCompleteEvent(event)">
 <mx:Style>
  
 </mx:Style>
 <mx:Script>
  <![CDATA[
   import mx.events.FlexEvent;
   
   //This bindable variable will be used to determine the
   //following:
   //_useStopWithImmediate = false => 
   // we use event.stopPropagation();
   //_useStopWithImmediate = true => 
   // we use event.stopImmediatePropagation();
   [bindable]
   private var _useImmediate:Boolean = false;

   public function get useImmediate():Boolean
   {
    return _useImmediate;
   }

   public function set useImmediate(value:Boolean):void
   {
    _useImmediate = value;
   }
   
   //Upone creation complete of this view
   protected function creationCompleteEvent(event:FlexEvent):void
   {
    //Add the listeners for DATA
    this.parent.addEventListener(DataEvent.DATA, displayEvent);
    this.parent.addEventListener(DataEvent.DATA, display2Event);
   }
   
   //When the parent view had capture a call for DataEvent.DATA
   private function displayEvent(event:Event):void{
    if(chkOption.selected){
     txtResult.text = "Event had been listened at " +
      "first field of " + this.parent.name + ".";
     //Stops the event from bubbling / moving upwards
     //Remove this line to see how you can listen for the 
     //same event in all the selected levels
     if(_useImmediate)
     {
      event.stopImmediatePropagation();
     }else{
      event.stopPropagation(); 
     }
    }
   }  
   
   //When the parent view had capture a call for DataEvent.DATA
   private function display2Event(event:Event):void{
    if(chkOption2.selected){
     txtResult2.text = "Event had been listened at " +
      "second field of " + this.parent.name + ".";
    }
   }  
  ]]>
 </mx:Script>
 <mx:VBox width="100%">
  <mx:HBox width="100%">
   <mx:Text id="txtResult" text=""/>
   <mx:Spacer width="100%"/>
   <mx:CheckBox id="chkOption" 
       label="Select me to check for Event 1"/>
  </mx:HBox>
  <mx:HBox width="100%">
   <mx:Text id="txtResult2" text=""/>
   <mx:Spacer width="100%"/>
   <mx:CheckBox id="chkOption2" 
       label="Select me to check for Event 2"/>
  </mx:HBox>
 </mx:VBox>
</mx:Canvas>
* Click here for the demo shown in this post.
^ Click here for the source files for the demo.

No comments:

Post a Comment