We've discussed this since the dawn of MG (I once had a knock-down argument with Doug Hughes about why this shouldn't be added), but I recently really saw the need for it. It'd be great to be able to add Flex widgets into existing Model-Glue applications without recreating wheels (or refactoring to full service layers), and there are also good cases out there for event-driven Model tiers. Admittedly, ColdBox also lit a fire under me to get this committed into SVN.
I've been working for the past few months, on and off, to add not just Flex integration but smooth Flex integration into Model-Glue. It's now committed to SVN, and you're welcome to use it. There's a new CFC in the application template (RemotingService). To make it part of your application, make a copy of it wherever you'd like and change the four variables it defines. Its base class does the rest.
A picture may say a thousand words on how to use this. I'll shoot for ten thousand: here's 13-minute a video.
If you'd like to skip the video, here's the highlights:
RemotingService.cfc acts as a Flash Remoting or SOAP endpoint for your application. If you didn't want any niceties on the Flex side, you could simply do this:
<mx:RemoteObject
id="mgProxy"
source="myapp.RemotingService"
destination="ColdFusion"
/>
<mx:Script><![CDATA
// invoke a model-glue event
mgProxy.remoteEvent("widget.list", data);
]]></mx:Script>
...adding result and fault handlers as necessary. That's not too clean though: since there's only a single method to call, you'd have to have your result figure out which event was called, delegate to a per-event handler, etc.
To make things nicer, I've wrapped deailing with Model-Glue's RemotingService into a .SWC that I'd recommend anyone doing this take advantage of. It's what I've put a fair amount of time into in order to make using Model-Glue from Flex "just work." It's in ModelGlue/unity/flex/bin/ModelGlueRemoting.swc, and contains three classes:
- com.modelglue.ModelGlueDelegate - Wraps a RemoteObject instance and provides an "invokeEvent" method allowing passing of an event name, parameters, and callback functions.
- com.modelglue.ProxyRequest
- The result of calling invokeEvent on a RemotingService, containing event data, the trace log, etc. Maps to the ModelGlue.unity.proxy.ProxyRequest CFC.
- com.modelglue.TraceGrid - DataGrid to show a Model-Glue event log.
To add it, just drop a copy of the .swc into your Flex Builder 3 project's "libs" directory, or use properties -> Flex Build Path -> Library Path to add a reference to the .swc to your project.
Once it's added, you no longer use the RemoteObject tag. Instead, you use the Model-Glue delegate:
<modelglue:ModelGlueDelegate
id="mgDelegate"
source="myapp.RemoteService"
destination="ColdFusion"
/>
Invoking an event now takes one required argument (the event name) and three optional arguments (an Object of event data, the result function for the call, and the fault function for the call). Here's how we'd get Widget with Id of 2:
mgDelegate.invokeEvent("widget.get", {widgetId:2}, widgetGetResult, widgetGetFault)
private function widgetGetResult(e:ResultEvent) {
// do stuff
}
private function widgetGetFault(e:FaultEvent) {
// do stuff
}
Easy, eh?
There's more. The "result" member of the ResultEvent is an AS3 class called com.modelglue.ProxyRequest. Its "data" member contains all the values from your event, so they're immediately available to you in Flex. Its "log" member contains the full Model-Glue trace, and there's even a custom DataGrid to help you show it!
Let's pretend we wanted to read widget with WidgetId 2 and see the trace. We can add the trace grid:
<modelglue:TraceGrid id="traceList" width="100%" height="100%" />
Now, we update our result to get the widget into a variable (AS3 <-> CFC conversions work!) and trace the event log:
private function widgetDeleteResult(e:ResultEvent) {
request:ProxyRequest = e.result as ProxyRequest;
// a "widget" variable was created by the MG event
someWidgetForm.widget = request.data.widget;
// show our trace log
traceList.dataProvider = request.log;
}
If Model-Glue encounters an exception, that'll be noted as well. Your ProxyRequest's "exception" property will be true, and the data.exception and data.stackTrace will be populated. "Exception" is basically the cfcatch structure, and the stackTrace is the full ColdFusion stack trace to the exception.
All of this is committed into SVN, and should make it into an official dot release after feedback is collected and revisions made.