5 Replies Latest reply on Feb 4, 2008 8:53 AM by Ukie_239

    Dispatch Event in Class

    Ukie_239
      I have a class which does a remoting call. Oncethe data is returned, i want to dispatch an event within the class so my main component can get the result and update the datagrid accordingly. I can dispatch events no problem when the dispatchEvent is not in a class. Unless i extend the EventDispatcher Class, i will get an error on:
      dispatchEvent(new Event("updateAssignedEmployeesE", true, true));

      I believe the Event is not dispatching because the parent component cannot listen to it. Is there something else i need to do on the parent component?

      package components.objects
      {
      import flash.events.Event;
      import flash.events.EventDispatcher;

      public class UpdateEmployeeToJob extends EventDispatcher
      {
      import mx.controls.Alert;
      import flash.events.MouseEvent;
      import flash.events.Event;
      import flash.events.EventDispatcher;
      include "../../scripts/Connection.as";
      public var result:Object = new Object();

      public function saveRecord(myObj:Object):void {
      //showObjValues(empJobObj);
      trace ("UD " + useDatabase)
      var passedVars : Array = new Array (myObj);
      gateway = new RemotingConnection(useDatabase);
      gateway.call("jobs.addUpdate", new Responder(onResult, onFault), passedVars);
      }

      private function onResult(r:Object):void {
      //rebind data
      trace ("EMPLOYEE ADDED " + r.toString());
      result = r;
      dispatchEvent(new Event("updateAssignedEmployeesE", true, true));

      }

      private function onFault(f:String):void {
      Alert.show ("Error Updating Employee to Job", "Update Error");
      }
      }
      }
        • 1. Re: Dispatch Event in Class
          Ratsnackbar Level 2
          If you create an active ValueObject class to hold your returned data. You then extend the event dispatcher in that ValueObject Class. Then populate that class and send it's own events off and multiple controls could then respond to the event and do what ever they need. I use this method when one of my classes already extends another class that does not have the EventDispatcher in it's inheritance chain.

          I wrote this for a friend as an example but you are welcome to it. It does not use a data grid but would be easy to use the same technique for that purpose.

          NOTE: Put all these files are in the same directory to test it or change the class paths.

          Something to note about this method is that you can specify the event name in the file that instantiates the ActiveVO so that only it knows to respond to the event.

          Hope this applies to what you need. Have a Nice Day!

          *******************Main Application************************
          <?xml version="1.0" encoding="utf-8"?>
          <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp();">
          <mx:Script>
          <![CDATA[

          import flash.events.MouseEvent;
          import flash.events.Event;
          import mx.controls.Alert;
          import mx.managers.PopUpManager;

          private var activeVO:ActiveVO;
          private var myEventName:String = "myCustomEventName";

          private function initApp():void{
          this.opener.addEventListener(MouseEvent.CLICK,doPopUp,false,0,true);
          this.activeVO = ActiveVO.getActiveVO();
          this.activeVO.eventName = myEventName;
          this.activeVO.addEventListener(this.myEventName,showActiveVOMessage,false,0,true);
          }

          private function showActiveVOMessage(event:Event):void{
          Alert.show("EventName: "+this.activeVO.eventName+"\nTitle: "+this.activeVO.title+"\nMessage: "+this.activeVO.message);
          }

          private function doPopUp(event:MouseEvent):void{
          var popUpWindow:CustomTitleWindow=CustomTitleWindow(PopUpManager.createPopUp(this, CustomTitleWindow, true));
          popUpWindow.title = "My Custom Title Window";
          PopUpManager.centerPopUp(popUpWindow);
          }
          ]]>
          </mx:Script>
          <mx:Metadata>
          [Event(name=this.myEventName, type="flash.events.Event")]
          </mx:Metadata>
          <mx:Button id="opener" label="Open Title Window" />
          </mx:Application>
          ******************End Main Application****************************

          *****************Custom TitleWindow******************************
          <?xml version="1.0" encoding="utf-8"?>
          <mx:TitleWindow xmlns:mx=" http://www.adobe.com/2006/mxml"
          layout="vertical"
          width="400"
          height="300"
          creationComplete="initApp();"
          close="closeThisWindow();"
          showCloseButton="true">
          <mx:Script>
          <![CDATA[
          import mx.managers.PopUpManager;

          private var activeVO:ActiveVO;

          private function initApp():void{
          this.activeVO = ActiveVO.getActiveVO();
          this.activeVO.title = this.title.toString();
          this.activeVO.message = "Message text set by CustomTitleWindow";
          }

          private function closeThisWindow():void{
          this.activeVO.ping();
          this.activeVO = null;
          PopUpManager.removePopUp(this);
          }
          ]]>
          </mx:Script>
          <mx:Metadata>
          [Event(name=this.activeVO.eventName, type="flash.events.Event")]
          </mx:Metadata>
          <mx:Text id="myText" text="Hello I am filler text so this window is not so dull! :D" />
          </mx:TitleWindow>
          **************************End Custom TitleWindow***********************

          **************************Active Value Object*****************************
          package
          {
          import flash.events.Event;
          import flash.events.EventDispatcher;
          import flash.events.IEventDispatcher;

          public class ActiveVO extends EventDispatcher
          {
          private var stTitle:String = "";
          private var stMessage:String = "";
          private var stEventName:String = "";
          private static var instance:ActiveVO;
          private static var allowInstance:Boolean = false;

          public function ActiveVO(target:IEventDispatcher=null)
          {
          if(allowInstance){
          super(target);
          } else {
          throw new Error("Error: use ActiveVO.getActiveVO() instead of new keyword");
          }
          }

          public static function getActiveVO():ActiveVO{
          if(instance == null){
          allowInstance = true;
          instance = new ActiveVO();
          allowInstance = false;
          }
          return instance;
          }

          public function set title(_header:String):void{
          this.stTitle = _header;
          }

          public function get title():String{
          return this.stTitle;
          }

          public function set message(_message:String):void{
          this.stMessage = _message;
          }

          public function get message():String{
          return this.stMessage;
          }

          public function set eventName(_eventName:String):void{
          this.stEventName = _eventName;
          }

          public function get eventName():String{
          return this.stEventName;
          }

          public function ping():void{
          var e:Event = new Event(this.eventName,true);
          this.dispatchEvent(e);
          }

          }
          }
          ***********************End Active ValueObject**************************
          • 2. Re: Dispatch Event in Class
            Ratsnackbar Level 2
            Oh Yeah! I forgot to mention this. I call then Active ValueObjects but I believe the actually pattern is called the Command Pattern if you wanted to read about it.
            • 3. Re: Dispatch Event in Class
              Ukie_239 Level 1
              hmmm, i cannot seem to get it to work, Can you give just a drop dead simple example of a class which dispenses an event and a component that can listen to the event? I cannot seem to get example u gave me to work

              Thanks
              • 4. Re: Dispatch Event in Class
                Ratsnackbar Level 2
                Ok then try this.
                ****************************************Application File Named what ever you like.*****************************************
                <?xml version="1.0" encoding="utf-8"?>
                <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" xmlns="*" layout="absolute" creationComplete="initApp();">
                <mx:Script>
                <![CDATA[

                import flash.events.Event;
                import mx.controls.Alert;

                private var myCustomEvent:CustomEvent;

                private function initApp():void{
                myCustomEvent = new CustomEvent();
                myCustomEvent.addEventListener("myEvent",showAlert,false,0,true);
                }

                private function doPing():void{
                myCustomEvent.ping();
                }

                private function showAlert(event:Event):void{
                Alert.show("Yep we see the Event");
                }
                ]]>
                </mx:Script>

                <mx:Metadata>
                [Event(name="myEvent", type="flash.events.Event")]
                </mx:Metadata>

                <mx:Button id="pingButton" label="Ping!" click="doPing();" />
                </mx:Application>
                ********************************************End Application File ************************************************

                **********Simple Custom Event Class: Name it CustomEvent.as****************************************

                package
                {
                import flash.events.Event;
                import flash.events.EventDispatcher;
                import flash.events.IEventDispatcher;

                [Event(name="myEvent", type="flash.events.Event")]

                public class CustomEvent extends EventDispatcher
                {

                public function CustomEvent(target:IEventDispatcher=null)
                {
                super(target);
                }

                public function ping():void{
                var e:Event = new Event("myEvent");
                this.dispatchEvent(e);
                }
                }
                }

                *******************************************End Simple Custom Event Class****************************************
                Put those two files into a new project and test. It should just show a ping button that when pressed calls the CustomEvent classes ping method which sends off an event.

                The Application itself is set to create the CustomEvent when it starts and add an event listener to it who's method simply shows an alert. Note the MetaData tag. This is what allows the application to be aware of the Event's existence and matches the Event that is declared in the CustomEvent Class.

                A few things to watch out for. When you have an event listener declared and a method set to handle the event. That methods constructor should have the event in it.

                I.E. This: showAlert(event:Event) Instead of this: showAlert().

                I am always forgetting to add the event into the constructor and spending hours trying to figure out why an event is not triggering as I expect. I am getting better at it but it's still a bugger because you will not always get a compiler error warning you about this.

                That's about as simple an example as I can think of. Hope it helps.
                • 5. Re: Dispatch Event in Class
                  Ukie_239 Level 1
                  Awesome, That works great. Thanks for the help