Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Welcome, Guest. Please login or register.
December 12, 2017, 08:27:52 PM
Home Help Search Login Register
News: Please DM @puremvc on Twitter to gain forum access. Spambots are why we can't have nice things.
Pages: [1]
Print
Author Topic: Proxy  (Read 3551 times)
Alci
Newbie
*
Posts: 5


View Profile
« on: January 27, 2010, 02:42:42 AM »

Hello everyone,
Thanks for answering my questions. Here's another problem i encountered during my development with pureMVC: The application i am currently working on need to load different type of xmls from time to time, I want to create a universal xml loader to load the data, then use different VOs to content them. I found the appskeleton demo is useful, but the LoadXMLDelegate uses classes from Flex, I am not sure how this can be done inside Flash.

The basic problem i am facing is, if i use a xml loader to load different data, how does it call back the same proxy which called it and transfer loaded xml back to that proxy? (without mx.rpc.IResponder) Obviously I can't create event type for every xml type.

Thanks
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW
« Reply #1 on: January 27, 2010, 09:45:49 AM »

Use the calling proxy's name as the async token.

First, make the loader itself a Proxy. Lets call it XMLProxy. That way it is accessible to all the other Proxies through the standard mechanisms and has the same lifecycle.

In your Proxies that need XML loaded, have them do this:

Code:
public function fetchXML():void // called from a command or mediator once view is prepped
{
   var xmlProxy:XMLProxy = facade.retrieveProxy(XMLProxy.NAME);
   xmlProxy.loadXML('myfile.xml', this.getProxyName());
}

Then in the XMLProxy:
Code:
public function loadXML( file:String, requestor:String )
{
   service.url=file; // an http service defined in onRegister
   var token:AsyncToken = service.send();
   token.requestor=requestor;
}

public function serviceResult( event:ResultEvent ):void // result event handler set in onRegister
{
   var requestingProxy:IProxy = facade.retrieve(event.token.requestor);
   requestingProxy.setData(event.result);  
}

Now the only problem is that the data is replaced in the requesting Proxy, but you don't know when it happens. You probably want a notification to go out from each proxy when it gets its data, so that other interested actors know they can now work with that Proxy's data.

So inside a requesting Proxy:
Code:
override public function setData(data:Object):void
{
   super.setData(data); // store the data
   sendNotification( THIS_PROXYS_UNIQUE_GOT_DATA_NOTE, data ); // sending the data is optional
}

Note that this Proxy's unique 'got data' note may be going out to let Mediators or a Command know that the Proxy has data and can be retrieved and manipulated. If the interested actors just want the data to work with, include it in this note and they can skip fetching the Proxy. But if you need to use the Proxy's methods to access and manipulate the data, then just the note with no data is sufficient.

-=Cliff>
Logged
Alci
Newbie
*
Posts: 5


View Profile
« Reply #2 on: January 27, 2010, 09:11:10 PM »

wow! that's simple! thank you very much cliff!!!
Logged
Alci
Newbie
*
Posts: 5


View Profile
« Reply #3 on: January 28, 2010, 12:48:47 AM »

Ooops, just realized that flash has no RPC
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW
« Reply #4 on: January 28, 2010, 08:52:15 AM »

Oh, sorry. I guess your original mention of IResponder as an option ruled out made me think you were using Flex.

In the case of Flash you need to roll your own Async Token pattern.

Here's an article about doing that:
http://corlan.org/2008/08/11/extending-actionscript-classes-to-provide-asynctoken-like-behavior/

Following that basic premise, you'd create a custom service component by extending URLLoader, give it an extra property to track your token. For our implementation we'll make a few deviations from that article.

We won't pass the token on the constructor, but make it a simple property. And we won't use data for the property name because that's already a property in the superclass. We'll call it token.

In the Proxy that uses this service, we'll also make sure that the service isn't interrupted by a new load request by returning a Boolean based on whether the token is set. And we'll clear the token after a result is handled.

Your new ServiceWithToken class:
Code:
package me.myapp.model.service
{
    public class ServiceWithToken extends URLLoader
    {

        private var token:Object;

        public function ServiceWithToken(  )
        {
            super();
        }

}

Back in your XMLProxy:
Code:
public function loadXML( file:String, requestor:String ):Boolean
{
   if (service.token == null) return false; // service is being used
   var request:URLRequest = new URLRequest(file);
   service.load(request); // a ServiceWithToken instance defined in onRegister
   var token:Object = new Object();
   token.requestor=requestor;
   service.token = token;
   return true;
}

public function serviceResult( event:ResultEvent ):void // Event.COMPLETE handler set in onRegister
{
   var requestingProxy:IProxy = facade.retrieve( service.token.requestor );
   requestingProxy.setData( new XML( service.data ) );  
   service.token=null;
}

So now there's one extra step for you to consider, which is that your proxies that will use the XMLProxy now need to wait if the XMLProxy is being used.

In SomeRandomXMLNeedingProxy:
Code:
public function fetchXML():void // called from a command or mediator once view is prepped
{
   var xmlProxy:XMLProxy = facade.retrieveProxy(XMLProxy.NAME);
   while ( ! xmlProxy.loadXML('myfile.xml', this.getProxyName() ) {} // brute-force blocking wait
}

The above is one way to handle that. The fetchXML method will simply knock at the door until someone lets it in. That is until the service call that's pending completes, the data is returned to the appropriate proxy and the token is cleared.

-=Cliff>
« Last Edit: January 28, 2010, 09:00:44 AM by puremvc » Logged
Pages: [1]
Print
Jump to: