Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

How do I make a function fire an event on a return, or make the rest of my application pause until this function returns?

Posted on 2009-04-08
16
Medium Priority
?
190 Views
Last Modified: 2013-11-11
Hello all, Actionscript newbie here.

I've got a function that is called when a button is clicked on a panel.  This function will contact a controller class, that in tern contacts a remote object (java servlet) to gather some data from a database.

I've noticed when I make this call, there seems to be no way for the system to "wait" for this entire process to wait until the call is done before it proceeds.  Is there a way to attach an event listener inside of my remote call on the actionscript side, such that when this event occurs, my program can continue on with the populated data?  Essentially what happens now is that the program continues on, and the data loads a few ms later.  I need the program to wait to get this data before proceeding, so I can populate the next form.  Is this a logical way to proceed, or should I look for another solution?

I've attached some code.  Hopefully it makes sense. Thanks all.
//this gets called when the button is pressed
private function TakeTest(event:MouseEvent):void{
if(incompleteList.selectedItem != null){
	questionController.TakeTest(incompleteList.selectedItem as Course);
	//need to figure out how to either pause here, or take the below and    handle it in another function when the TakeTest method finishes it's business.
	questionViewerPanel.enabled = true;
	questionViewerPanel.visible = true;
	questionViewerPanel.includeInLayout = true;
	questionViewerPanel.GetQuestionAndDisplay();
}
}
 
QuestionController.TakeTest is below:
 
public function TakeTest(courseToTake:Course):void{
			
       var ro:RemoteObject = new RemoteObject("questionSvc");
			
       var token:AsyncToken = ro.getQuestionsForCourse(courseToTake.name);
			
	token.addResponder(new ItemResponder(loadQuestions,onFault));
        	
}
		
private function loadQuestions(event:ResultEvent, token: AsyncToken = null) :void{
	for each(var obj:Object in event.result){
                var tObj2:Question = obj as Question;
                		//add item to array collection
                                  loadedQuestions.addItem(tObj2);
        }
        //I'd like to either return something here, back up to my original page, or fire an event here that I can listen out for.
                		
}

Open in new window

0
Comment
Question by:csciguy81
  • 8
  • 8
16 Comments
 
LVL 37

Expert Comment

by:zzynx
ID: 24102045
Flex is all about events.

1) Make your loadQuestions() function throw a custom event (say QUESTIONS_LOADED)
2) Listen for it in your TakeTest function (cf attached code snippet)


All about Custom Events : http://livedocs.adobe.com/flex/3/html/help.html?content=createevents_1.html
private function TakeTest(event:MouseEvent):void{
   if(incompleteList.selectedItem != null){
          questionController.addEventListener(MyEvent.QUESTIONS_LOADED, function():void {
              questionViewerPanel.enabled = true;
              questionViewerPanel.visible = true;
              questionViewerPanel.includeInLayout = true;
              questionViewerPanel.GetQuestionAndDisplay();
          });
          questionController.TakeTest(incompleteList.selectedItem as Course);
   }
}

Open in new window

0
 

Author Comment

by:csciguy81
ID: 24102064
Can anything throw an event?  Even if it's some piece of embedded actionscript that is down inside of a controller?
0
 
LVL 37

Accepted Solution

by:
zzynx earned 2000 total points
ID: 24102240
>> Can anything throw an event?
Every class that extends EventDispatcher

As the docs (http://livedocs.adobe.com/flex/3/langref/flash/events/EventDispatcher.html) say:
In general, the easiest way for a user-defined class to gain event dispatching capabilities is to extend EventDispatcher. If this is impossible (that is, if the class is already extending another class), you can instead implement the IEventDispatcher interface, create an EventDispatcher member, and write simple hooks to route calls into the aggregated EventDispatcher.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 37

Expert Comment

by:zzynx
ID: 24102265
Handling Events: http://learn.adobe.com/wiki/display/Flex/3b.+Handling%20Events
(and press the next button to see the demo)
0
 

Author Comment

by:csciguy81
ID: 24103178
So would my controller then need to extend Event?  The TakeTest function mentioned above lives on a flex component itself (just a simple panel with a button and some text).  The question controller itself is just an actionscript class.  Would that controller class need to extend Event?

The controller itself is nothing more than a collection of functions that provide remote object calls into my web service.
0
 

Author Comment

by:csciguy81
ID: 24103227
Update.  Here is my QuestionEvent class I wrote.  Now, how do I fire this off from inside of a function that lives inside of another class?


package Custom_Events
{
	import flash.events.Event;
 
	public class QuestionEvent extends Event
	{
		
		
		public function QuestionEvent(type:String, 
            isEnabled:Boolean=false) {
                // Call the constructor of the superclass.
                super(type);
    
                // Set the new property.
                this.isEnabled = isEnabled;
        }
 
        // Define static constant.
        public static const QUESTIONS_UNLOADED:String = "questionsUnloaded";
        public static const QUESTIONS_LOADED:String = "questionsLoaded";
 
        // Define a public variable to hold the state of the enable property.
        public var isEnabled:Boolean;
 
        // Override the inherited clone() method.
        override public function clone():Event {
            return new QuestionEvent(type, isEnabled);
        }
 
		
	}
}

Open in new window

0
 

Author Comment

by:csciguy81
ID: 24103257
I threw this inside of my function in the Question Controller that loads the questions.  It's however telling me, "call to a possibly undefined method dispatchEvent." and erroring out.


var questionEventObj:QuestionEvent = new QuestionEvent("questionsLoaded");
						questionEventObj.isEnabled=true;
						dispatchEvent(questionEventObj);

Open in new window

0
 
LVL 37

Expert Comment

by:zzynx
ID: 24104678
Concerning your own event, this is sufficient:

package Custom_Events {
      
      import flash.events.Event;

      public class QuestionEvent extends Event      {

                public static const QUESTIONS_UNLOADED:String = "questionsUnloaded";
                public static const QUESTIONS_LOADED:String = "questionsLoaded";

            public function QuestionEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) {
                  super(type, bubbles, cancelable);
            }
      }
}

>> So would my controller then need to extend Event?
No, EventDispatcher
>> It's however telling me, "call to a possibly undefined method dispatchEvent."
That's because it doesn't extends EventDispatcher
0
 
LVL 37

Expert Comment

by:zzynx
ID: 24104697
So,

public class YourControllerClass extends EventDispatcher {

   ...
   private function loadQuestions(event:ResultEvent, token: AsyncToken = null) :void{
        ...
       dispatchEvent( new QuestionEvent(QuestionEvent.QUESTIONS_LOADED, true /*bubbling*/) );
   }

}

and

private function TakeTest(event:MouseEvent):void{
   if(incompleteList.selectedItem != null){
          questionController.addEventListener(QuestionEvent.QUESTIONS_LOADED, function():void {
              questionViewerPanel.enabled = true;
              questionViewerPanel.visible = true;
              questionViewerPanel.includeInLayout = true;
              questionViewerPanel.GetQuestionAndDisplay();
          });
          questionController.TakeTest(incompleteList.selectedItem as Course);
   }
}
0
 
LVL 37

Expert Comment

by:zzynx
ID: 24106338
Let me make a correction.
The Flex API Doc says: "You are required to override the Event.clone() method in your subclass."
Why it's important to override clone in your custom Event class?
http://manishjethani.com/blog/2008/04/04/why-its-important-to-override-clone-in-your-custom-event-class/
http://www.allmas-tn.com/200810257/always-override-the-clone-method-for-your-custom-events.html
http://michaelangela.wordpress.com/2008/04/03/implement-clone-in-custom-events/
http://life.neophi.com/danielr/2006/06/events_in_flex_2.html

So to avoid problems later on, you'd better add that clone() function to your QuestionEvent class:
package Custom_Events {
      
      import flash.events.Event;
 
      public class QuestionEvent extends Event      {
 
            public static const QUESTIONS_UNLOADED:String = "questionsUnloaded";
            public static const QUESTIONS_LOADED:String = "questionsLoaded";
 
            public function QuestionEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) {
                  super(type, bubbles, cancelable);
            }
 
            override public function clone():Event {
                return new QuestionEvent(type, bubbles, cancelable);
            }
            
      }
}

Open in new window

0
 

Author Comment

by:csciguy81
ID: 24106932
Yeah, I saw in the docs that I needed to implement Clone, so I threw that in there.  Let me modify my QuestionController to extend EventDispatcher and I'll report back.  Thanks for the help so far.  Hopefully I'll be able to close this one out today.
0
 

Author Comment

by:csciguy81
ID: 24107238
Ok, I got something working, but I have one last question here in these regards.

Instead of having the QuestionController add an event listener, can I make the panel itself have one?  The panel in which the "TakeTest" function resides in has a few other functions inside of <mx:Script> tags that are used on the page itself (to control some loading, etc).  

If I say something like:
this.addEventListener(QuestionEvent.QUESTIONS_LOADED, function():void{//etc}
the listener never listens.

The "this", in this case, would be the component itself (Canvas) right?

If I say something like:
questionController.AddEventListener(QuestionEvent.QUESTIONS_LOADED, function():void){//etc}
the listener listens, everything works as expected.

Why is that?
0
 
LVL 37

Expert Comment

by:zzynx
ID: 24107318
>> If I say something like:
>> this.addEventListener(QuestionEvent.QUESTIONS_LOADED, function():void{//etc}
>> the listener never listens.
Well, it listens but it never "hears" something ;o)
By writing that, you listen for this (Canvas, Panel or whatever) to dispatch that kind of event.
But since we wrote our code in a way that the controller performs a dispatchEvent(...) we should listen on that one for the event.

Assume we have two person classes John and Pete.
If in John we perform a yell("Hello world");
then in we could write code like this:

var pete:Pete = new Pete();
pete.addListener(Yell, ....);

We listen for Pete to yell, while it's John we made yell at us. See?
0
 

Author Comment

by:csciguy81
ID: 24107405
Hmm.  Interesting.

I think I might have a somewhat better understanding now.  Thanks for the great help!
0
 

Author Closing Comment

by:csciguy81
ID: 31568248
Great suggestive help.  Thanks a lot.
0
 
LVL 37

Expert Comment

by:zzynx
ID: 24107446
Glad I could help.
Thanx 4 axxepting
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In my long career of working as an actionscript developer, I had spent sleepless night often working hard to solve some small problems which actually took a lot of my development time; later found out the solutions to be a line or two. Here are s…
The last time I worked with Flash and Socket connections was in AS1. A recent project required flash connecting to a Socket, and sending receiving information - we figured it would be easy enough - we all know about the socket policy documents and c…
In this tutorial viewers will learn how to create a basic motion tween animation in Flash Open a new document in Flash: Draw/import an image: Press CTRL + F8 to convert it into a graphic symbol: Select a frame (how long you want the tween to last): …
In this tutorial viewers will learn how to create a basic shape tween animation in Flash including shape hints for smooth animation Open a new document in Flash: Draw a shape: Select another frame (how long you want the tween to be): Right click and…

916 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question