views:

1560

answers:

2

What would be a clever way to make a 'please wait' control for a Flex application for long running operations like calling a webservice.

I am not asking about the graphical portion of it - just the 'controller' part. How should I trigger it and hide it. I am planning to make just a simple canvas with text in.

For instance :

  • can I somehow intercept all web service calls - and not have to activate it for every web service
  • how should i add it to my canvas. should it be added to 'stage' as a top level component?
  • should it have a 'cancel' button to cancel the web service request if it takes too long. that sounds kind of complicated because I'm not even sure if I can terminate a running async web request?

FYI: This is for a reporting application so long running queries are to be expected

+1  A: 

One way I have done it in the past is to have a global integer and increment / decrement the value based on the web services running. When the counter was 0, I would hide the loading text, when it was greater than 0, I would display the loading text. Here is a simplified version of it:


<mx:Application>
    <mx:Script>
        [Bindable]public var ws_count:int = 0;
    </mx:Script>
    <mx:Label text = "loading..." visible="{ws_count > 0}" />
</mx:Application>


I then had a little helper class to control the global counter:


package ws {
    import mx.core.Application;
    public class WSCounter {
        public static function sent():void {
            Application.application.ws_count += 1;
        }
        public static function receive():void {
            Application.application.ws_count -= 1;
        }
    }
}

Then all that needs to be done is to call the helper function when a web service is called...e.g:


import ws.WSCounter;
import mx.rpc.http.HTTPService;

var srv:HTTPService = new HTTPService();
srv.url = "http://localhost/service.py";
srv.addEventListener(ResultEvent.RESULT,function(event:ResultEvent):void {
    WSCounter.receive();
});
srv.send();
WSCounter.sent();

I always have thought there was a better way to do this, like you said have some type of hook to detect if a service is running...I'm looking forward to other responses in this post...

mmattax
interesting idea. this is why i asked the question in the first place - just to see what people did. i'm just a little scared about its reliability. you'd at least need to add a 'receive' event to the faultListener too
Simon_Weaver
That's correct I skipped that fault listener to keep it brief...It works well, but at the same time I hope someone posts something better...
mmattax
A: 

If you are using a framework like Cairngorm or similar that implements MVC, the straightforward approach is to update a "global" variable (via a Singleton object) thats bound to UI Component's (ie. titleWindow under main mxml or whatever) visible attribute. the variable will be updated to true during execute() and false when it reaches result or fault callback methods.
You can add a "cancel" button that resets the variable to "false" but it doesnt mean the server will stop the async call. i dont know how to stop it and prevent it from returning a data from a cancelled method call. taking a quick look at the ASDoc, remoteobject does have a disconnect() method that discards all the pending request responders. im not sure if its the elegant/right way to do it
if you do not want to set it for every web service call, you might wanna use a custom event chaining (see http://www.herrodius.com/blog/80 for ideas) so that you only have to set it once if you are calling single or multiple services.

Stephen