Dynamic RemoteObject defined by settings in an XML file
In my CF United 2008 presentation on Charting with Flex and ColdFusion, I demonstrated a nifty actionscript function to dynamically create a remoteObject without needing to use services-config.xml. (The code is nearly identical to code written by Mike Nimer, but lovingly frosted with glucose... rr tweaked for my needs) I also mentioned that using this, it would be possible to have an external settings file read at runtime that defined your remote object endpoint, without needing to use an annoying services-config.xml file and allowing run-time configuration of your remote data services.
Why would you want to do that? (you might ask...) Well, the short answer is that you can re-configure the server that your app talks to without re-compiling your flex app, which is really important if you do any type of QA testing.
So this post is all about how to do that thing i just described.
To start, lets create a settings.xml file in the root of our source. Lets say it looks like this:
<Settings>
<destination>ColdFusion</destination>
<channelName>my-cfamf</channelName>
<gatewayUri>http://yourhost.com/flex2gateway/</gatewayUri>
<cfc>your.path.to.cfc</cfc>
<useSsl>false</useSsl>
</Settings>
Here is the main app code, and then I will explain:
<mx:Application
layout="absolute"
xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="onCreationComplete()"
>
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.controls.Alert;
import mx.rpc.remoting.RemoteObject;
import mx.messaging.ChannelSet;
import mx.messaging.channels.AMFChannel;
import mx.messaging.channels.SecureAMFChannel;
private var strDestination:String;
private var strChannelName:String;
private var strGatewayUri:String;
private var strCfc:String;
private var bUseSsl:Boolean;
private var myRemoteObject:RemoteObject;
private function onCreationComplete():void
{
hsSettings.send();
}
private function handleLoadSettings(event:ResultEvent):void
{
strDestination = event.result.destination;
strChannelName = event.result.channelName;
strGatewayUri = event.result.gatewayUri;
strCfc = event.result.cfc;
if (event.result.useSsl == "true")
bUseSsl = true;
else
bUseSsl = false;
myRemoteObject = configRemoteObject(strDestination,
strChannelName,
strGatewayUri,
strCfc,
bUseSsl);
}
private function callMyRpc():void
{
// add event listeners to it
myRemoteObject.myRpc.addEventListener("result",handleMyResult);
myRemoteObject.myRpc.addEventListener("fault",errorHandler);
// initiate the RPC call
myRemoteObject.myRpc("param 1","param 2");
}
private function handleMyResult(event:ResultEvent):void
{
// do something with event.result;
}
private function errorHandler(event:FaultEvent):void
{
Alert.show("An error occurred: \n\n"+event.fault);
}
private function configRemoteObject(destName:String, channelName:String, gatewayURI:String, cfc:String, useSsl:Boolean):RemoteObject
{
var cs:ChannelSet = new ChannelSet();
if (useSsl)
cs.addChannel(new SecureAMFChannel(channelName, gatewayURI));
else
cs.addChannel(new AMFChannel(channelName, gatewayURI));
var ro:RemoteObject = new RemoteObject();
ro.destination = destName;
ro.channelSet = cs;
ro.source = cfc;
return ro;
}
]]>
</mx:Script>
<mx:HTTPService id="hsSettings" url="settings.xml" resultFormat="e4x"
result="handleLoadSettings(event)" fault="errorHandler(event)" />
<mx:Button label="Do Something" click="callMyRpc()" />
</mx:Application>
So here is how this works. When the flex app finishes loading, it will call onCreationComplete(), which tells the http service to load the settings.xml file. When the http service completes, it calls handleLoadSettings(), which parses the settings.xml file and pulls out our values into local private vars, and then calls the configRemoteObject() function to build the dynamic remote object.
At this point, you use your remote object from actionscript, simply remembering to add any event handlers you want before invoking a function name, so for example "callMyRpc()" where "myRpc" is a function in the cfc you specified in your settings.xml file (the cfc setting of course, which is the dotted path to your CFC, but without the ".cfc" on the end).
As long as you add event handlers, you can define and call as many functions on that CFC as you want. If you want to call against a different CFC, then create a new RemoteObject using the same method.
Hope this helps many Flex Coders to break free from services-config.xml!

http://www.mikenimer.com/index.cfm/2007/1/10/Bye-b...