3 Replies Latest reply on Aug 10, 2010 9:49 AM by mike_morales

    Custom Event Bubble

    SolB40

      I'm new to flex and how it handles Event Bubbling.  I can make a custom event work with this code:

       

      <?xml version="1.0" encoding="utf-8"?>
      <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                     xmlns:s="library://ns.adobe.com/flex/spark"
                     xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
                     applicationComplete="init()" name="app">
          <fx:Declarations>
              <!-- Place non-visual elements (e.g., services, value objects) here -->
          </fx:Declarations>
          <fx:Script>
              <![CDATA[
                  import flash.events.Event;
                  import mx.controls.Alert;
                  private function init():void {
                      addEventListener("myEvent",testListener);
                      var testEvent:Event = new Event("myEvent",true);
                      dispatchEvent(testEvent);
                  }
                 
                  private function testListener(event:Event):void {
                      Alert.show("Trigger Worked");
                  }
              ]]>
          </fx:Script>
      </s:Application>

      But when I break out the code so the Event fires in a class the parent does not catch it.

      MyEvent.as file:

      package comp {
          import flash.display.MovieClip;
          import flash.events.Event;
          public class MyEvent extends MovieClip{
              public function MyEvent() {
                  var testEvent:Event = new Event("myEvent",true);
                  dispatchEvent(testEvent);
              }
          }
      }

       

      TestEvents.mxml file:

      <?xml version="1.0" encoding="utf-8"?>
      <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                     xmlns:s="library://ns.adobe.com/flex/spark"
                     xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
                     applicationComplete="init()" name="app">
          <fx:Declarations>
              <!-- Place non-visual elements (e.g., services, value objects) here -->
          </fx:Declarations>
          <fx:Script>
              <![CDATA[
                  import comp.MyEvent;
                  import flash.events.Event;
                  import mx.controls.Alert;
                  private function init():void {
                      addEventListener("myEvent",testListener);
                      var tempEvent:MyEvent = new MyEvent();
                  }
                  private function testListener(event:Event):void {
                      Alert.show("Trigger Worked");
                  }
              ]]>
          </fx:Script>
      </s:Application>

       

      I know I'm missing something simple.  Could someone please point me in the correct direction.

       

      Thanks,

       

      Sol

        • 1. Re: Custom Event Bubble
          mike_morales Level 2

          Try using a static constant in your class instead;

           

          so in your MyEvent.as class use:

           

          public static const MY_EVENT:String = 'myEvent';

          ...

          dispatchEvent(new Event(MyEvent.MY_EVENT));


          }

           

          -----------------------

           

          now in your app, you would listen for "Event.MY_EVENT" like so,

           

          var tempMyEvent:MyEvent = new MyEvent();

          tempMyEvent.addEventListener(MyEvent.MY_EVENT, myEventHandler);

           

          private function myEventHandler(event:Event):void{

               // execute code here . . .

          }

           

           


          * having a public constant declared in your class makes it 'explicitly' available - therefore, when you use 'addEventListener' you can explicity state the name of your class, followed by your constant, so in the above example, you would use use addEventListener(MyEvent.MY_EVENT,handler);

          1 person found this helpful
          • 2. Re: Custom Event Bubble
            SolB40 Level 1

            Thanks for the help!!!  I got it to work using most of your code.  The only change I had to make was move the dispatchEvent out of the construtor and into it's own function.  That way the listener is definded before it fires.

             

             

            Now I noticed you added the listener to the object itself is this bubbling?  I thought if you have bubbling turned on the main app can have the listener and if a child fires an event it would bubble up.  If the listerner is not on the MyEvent class it does not work.

             

             

            Here is the new Working code if you take the : tempMyEvent off this line:

             

            addEventListener(MyEvent.MY_EVENT, myEventHandler);

             

            it does not work

             

            Should it?  Should the event bubble up and still be fired?

             

            Below is working code:

            MyEvent.as

            package comp {
                import flash.display.MovieClip;
                import flash.events.Event;
               
                public class MyEvent extends MovieClip{
                    public static const MY_EVENT:String = 'myEvent';
                    public function MyEvent() {}
                    public function disEventTest():void {
                        dispatchEvent(new Event(MyEvent.MY_EVENT,true));
                    }
                }
            }

             

            TestEvents.mxml

             

            <?xml version="1.0" encoding="utf-8"?>
            <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                           xmlns:s="library://ns.adobe.com/flex/spark"
                           xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
                           applicationComplete="init()" name="app">
                <fx:Declarations>
                    <!-- Place non-visual elements (e.g., services, value objects) here -->
                </fx:Declarations>
                <fx:Script>
                    <![CDATA[
                        import comp.MyEvent;
                        import flash.events.Event;
                        import mx.controls.Alert;
                        private function init():void {
                            var tempMyEvent:MyEvent = new MyEvent();
                            tempMyEvent.addEventListener(MyEvent.MY_EVENT, myEventHandler);
                            tempMyEvent.disEventTest();
                        }
                        private function myEventHandler(event:Event):void {
                            Alert.show("Trigger Worked");
                        }
                    ]]>
                </fx:Script>
            </s:Application>

            Thanks again for your help this will at least get me moving forward again.

             

            Sol

            • 3. Re: Custom Event Bubble
              mike_morales Level 2

              Hi Sol,

               

              You are correct, you must add the event listener to the instance before dispatching the event, cuz otherwise it would never get heard.  Typically, though, you wouldn't dispatch your event in your constructor.  Usually, as you know, you'd have your custom class do something, then dispatch an event after it does its job. Something like yourClass.addThese(val1:int, val2:int) then once it's done it would dispatch an event called "ADDITION_COMPLETE" then your app that is listening for this particular event (myTempInstance.addEventListener(YourClass.ADDITION_COMPLETE,handler) could do something, say, send the calculated value to a database.

               

              You could also have your class subtract variables for example, subtractThese(val1:int, val2:int) then after it does this, dispatch a second event called "SUBTRACTION_COMPLETE", then your app could also listen for "SUBTRACTION_COMPLETE" and send the resulting value to a database for example. So, in the above, you'd have your app listen to 2 events from your instance, but you could have as many as you like.

               

              so it would look something like this in your main app:

               

              private var tempClass:MyClass = new MyClass();

              tempClass.addEventListener(MyClass.ADDITION_COMPLETE,additionHandler);

              tempClass.addEventListener(MyClass.SUBTRACTION_COMPLETE,subtractionHandler);

               

              tempClass.addThese(152,562);

              tempClass.subtractThese(55,32);

               

              private function additionHandler():void{

                  var tempAdditionValue:uint = tempClass.value;

              }

              private function subtrationHander():void{

                  var tempSubtractionValue:int = tempClass.subtractedValue;

              }

               

               

               

              And making the event names constants, makes them available to your app. If you did not use contants, then you'd have to make your event instances 'public' or 'protected' so your app could access them. Glad you got it working.