Using ColdBox to power Flex
April 10, 2009
I'm using ColdBox (the 2.6.3 release) for the first time on a client site and one of the reasons for choosing it is the ColdBox Proxy. This allows you to use ColdBox as an event-driven framework for handling remoting. What is really neat about it is that you can monitor remote calls which is a great way of debugging your applications.
When you download the ColdBox bundle there a sample application called ColdboxFlexTester which contains a flex application (compiled to swf) which uses RemoteObject to call ColdBox.
When I copied the supplied mxml file into my Flex Builder 3 it wouldn't compile (I think it was written for Flex 2) so I thought I'd share my updated version for anyone else who wants it.
ColdBoxFlexTester.mxml (updated)
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.rpc.remoting.mxml.RemoteObject;
import mx.rpc.events.FaultEvent;
import mx.events.ItemClickEvent;
import mx.rpc.events.ResultEvent;
import mx.controls.Alert;
import mx.collections.ArrayCollection;
[Bindable]
public var aResult:Array;
//My Proxy Path
public var cbProxyPath:String = "coldbox.samples.applications.ColdboxFlexTester.webroot.coldboxproxy";
public var fwSetting:Boolean = false;
/* PUBLIC FAULT Handler */
public function faultHandler(event:FaultEvent):void{
Alert.show(event.fault.toString());
}
/* UTILITY METHOD TO GET A CBPROXY OBJECT */
public function getColdBoxProxy():RemoteObject{
var cProxy:RemoteObject = new RemoteObject( "ColdFusion" );
cProxy.source= cbProxyPath;
cProxy.showBusyCursor = true;
cProxy.addEventListener(FaultEvent.FAULT,faultHandler);
return cProxy;
}
/* GET TEST ARRAY */
public function handleArrayResults(event:ResultEvent):void{
var coldboxProxy:RemoteObject = getColdBoxProxy();
aResult=event.result as Array;
coldboxProxy.addEventListener(ResultEvent.RESULT,handleArrayResults);
}
public function getRemoteArray():void{
var cProxy:RemoteObject = getColdBoxProxy();
cProxy.process.addEventListener("result",handleArrayResults );
cProxy.process({event:"ehFlex.getIntroArrays"});
}
/* GET SETTINGS */
public function handleSettingResults(event:ResultEvent):void{
var setting:String = event.result as String;
if ( setting.length == 0)
lbl_setting_results.text = "Invalid Setting";
else
lbl_setting_results.text = setting;
}
public function getSetting():void{
var cProxy:RemoteObject = getColdBoxProxy();
cProxy.getSetting.addEventListener("result",handleSettingResults );
cProxy.getSetting(setting.text, fwSetting);
}
public function setFWSetting(event:ItemClickEvent):void{
if (event.currentTarget.selectedValue == "application"){
fwSetting = false;
}
else{
fwSetting = true;
}
}
/* Translation */
public function handleLanguageTranslation(event:ResultEvent):void{
var oLanguages:Object = new Object();
var key:String;
var array:Array = new Array();
//Get the Languages
oLanguages = event.result;
//Loop and set
for( key in oLanguages ){
array.push( { Language: key, Translation: oLanguages[key] } );
}
var collection:ArrayCollection = new ArrayCollection(array);
grid_language.dataProvider = collection;
}
public function getTranslation():void{
var cProxy:RemoteObject = getColdBoxProxy();
cProxy.process.addEventListener("result",handleLanguageTranslation );
cProxy.process({event:"ehFlex.getIntroStructure"});
}
/* Populate comboboxes */
public function handleGetConfigSettings(event:ResultEvent):void{
var settings:Object = new Object();
var key:String;
var appSettingsArray:Array = new Array();
var array:Array = new Array();
//Get setting structure.
settings = event.result as Object;
for( key in settings){
appSettingsArray.push( key );
array.push( { Setting: key, Value: settings[key] } );
}
//Populate comboboxes
cb_appsettings.dataProvider = appSettingsArray;
//Populate data grid
var collection:ArrayCollection = new ArrayCollection(array);
dg_settings.dataProvider = collection;
}
public function handleGetFrameworkSettings(event:ResultEvent):void{
var settings:Object = new Object();
var key:String;
var fwSettingsArray:Array = new Array();
var array:Array = new Array();
settings = event.result as Object;
for( key in settings){
fwSettingsArray.push(key);
array.push( { Setting: key, Value: settings[key] } );
}
//Populate comboboxes
cb_fwsettings.dataProvider = fwSettingsArray;
//Populate data grid
var collection:ArrayCollection = new ArrayCollection(array);
dg_settings.dataProvider = collection;
}
public function populateCB( type:String ):void{
var cProxy:RemoteObject = getColdBoxProxy();
if( type == "appsettings" ){
cProxy.getConfigSettings.addEventListener("result",handleGetConfigSettings );
cProxy.getConfigSettings();
}
else{
cProxy.getColdboxSettings.addEventListener("result",handleGetFrameworkSettings );
cProxy.getColdboxSettings();
}
}
//ANNOUNCE INTERCEPTION
public function handleInterception(event:ResultEvent):void{
var coldboxProxy:RemoteObject = getColdBoxProxy();
Alert.show("Interception announced: " + event.result);
readLog();
coldboxProxy.addEventListener(ResultEvent.RESULT,handleInterception);
}
public function announceInterception():void{
var cProxy:RemoteObject = getColdBoxProxy();
cProxy.announceInterception.addEventListener("result",handleInterception );
cProxy.announceInterception("onLog",txtarea_interceptor.text);
}
/* LOG */
public function handleReadLog(event:ResultEvent):void{
var coldboxProxy:RemoteObject = getColdBoxProxy();
var logContents:String = event.result as String;
txtarea_logcontents.text = logContents;
coldboxProxy.addEventListener(ResultEvent.RESULT,handleReadLog);
}
public function readLog():void{
var cProxy:RemoteObject = getColdBoxProxy();
cProxy.process.addEventListener("result",handleReadLog );
cProxy.process({event:"ehFlex.readLog"});
}
/* READ THE CACHE */
public function handleCacheResults(event:ResultEvent):void{
var cacheItems:Object = new Object();
var key:String;
var array:Array = new Array();
cacheItems = event.result;
for( key in cacheItems ){
array.push( { item:key, total: cacheItems[key] });
}
var collection:ArrayCollection = new ArrayCollection(array);
cachechart.dataProvider = collection;
}
public function readCache():void{
var cProxy:RemoteObject = getColdBoxProxy();
cProxy.process.addEventListener("result",handleCacheResults );
cProxy.process({event:"ehFlex.getCacheItemTypes"});
}
]]>
</mx:Script>
<mx:Button label="Ask ColdBox For Array" click="getRemoteArray()" x="10" y="20" width="170"/>
<mx:List id="myArrayResults" dataProvider="{aResult}" width="170" x="10" y="50"/>
<!--Setting-->
<mx:TextInput x="208" y="50" id="setting" text="write a setting here"/>
<mx:Button x="376" y="50" label="Get ColdBox Setting" click="getSetting()"/>
<mx:Label x="523" y="50" text="Results:" fontWeight="bold"/>
<mx:Label x="573" y="50" width="280" id="lbl_setting_results"/>
<mx:RadioButtonGroup id="rbg_settings" itemClick="setFWSetting(event);"/>
<mx:RadioButton x="208" y="20" label="Application Settings"
selected="true"
id="rb_appsettings"
groupName="rbg_settings"
value="application" />
<mx:RadioButton x="350" y="20" label="Framework Settings"
id="rb_fwsettings"
groupName="rbg_settings"
value="framework" />
<mx:Label x="10" y="214" text="Translate Hello into languages" fontWeight="bold"/>
<!-- Transaltion -->
<mx:Button x="10" y="240" label="ColdBox Translate" click="getTranslation()"/>
<mx:DataGrid x="10" y="270" width="184" id="grid_language" height="110">
</mx:DataGrid>
<!--App + FW Settings-->
<mx:ComboBox x="208" y="89" width="226" id="cb_appsettings"></mx:ComboBox>
<mx:ComboBox x="208" y="119" width="226" id="cb_fwsettings"></mx:ComboBox>
<mx:Button x="453" y="89" label="Populate App Settings" click="populateCB('appsettings')" width="175"/>
<mx:Button x="453" y="119" label="Populate Coldbox Settings" click="populateCB('coldboxsettings')"/>
<mx:DataGrid x="208" y="149" width="645" height="212" id="dg_settings" horizontalScrollPolicy="on">
</mx:DataGrid>
<mx:PieChart id="cachechart"
height="190"
width="205"
showDataTips="true" x="10" y="450">
<mx:series>
<mx:PieSeries field="total" nameField="item"
labelPosition="callout" />
</mx:series>
</mx:PieChart>
<mx:Button x="45" y="420" label="Get Cache Chart" click="readCache()"/>
<!-- Announce Interception -->
<mx:TextArea x="658" y="113" id="txtarea_interceptor" text="Please text here to send for interception" width="195" height="33"/>
<mx:Button x="674" y="89" label="Announce Interception" click="announceInterception()"/>
<!-- Read Log -->
<mx:TextArea x="223" y="369" width="630" height="241" id="txtarea_logcontents" wordWrap="true" editable="false" enabled="true" color="#2CA7E0" backgroundColor="#010101"/>
<mx:Button x="474" y="618" label="Read Log" click="readLog()"/>
</mx:Application>
The sample application also has several sample methods in the coldboxproxy.cfc. The process method is the one that you are most likely to use, as it simply passes the remote request onto your existing event handler and returns the result to flex.
For the application I'm building, the data I was after was only relevant to my Flex application so I didn't really want to write a whole bunch of event handlers just for my Flex application. The developers of ColdBox have clearly thought about this and have made it really simple.
I have a service layer which has methods which give me access to the database. To call my service layer from the coldboxproxy.cfc I simply had to add this method for Flex to call:
<cffunction name="getQuestions"
output="false"
access="remote"
returntype="any"
hint="Process a remote call and return data/objects back.">
<cfset var result = "" />
<cfset var QuizService = "" />
<!--- ask ColdBox to get the QuizService bean from ColdSpring --->
<cfset QuizService = getPlugin( "ioc" ).getBean( "QuizService" ) />
<!--- pass the argumentCollection from Flex to the getQuestions method and return the result --->
<cfset result = QuizService.getQuestions( argumentCollection=arguments ) />
<cfreturn result />
</cffunction>
That's it. Simple and that suits me!
- Posted in:
- ColdFusion
- Coldbox
- Coldspring
No comments
Leave a comment
If you found this post useful, interesting or just plain wrong, let me know - I like feedback :)




