In my first cuts of Model-Glue: Flex, I wrote a bit of helper called an Autoproxy that let you call a service from a controller, passing along a reference to Result and Fault callback functions. It was simple, familiar, and did away with manually dealing with AsyncToken and the like.
Model-Glue: ColdFusion
I'm happy to announce that I released Model-Glue 2.0 (specifically, Model-Glue 2.0.304!) earlier this morning.
Head over to the new Model-Glue Web Site to learn more!
Model-Glue: Flex
Model-Glue: Flex is a conceptual port of Model-Glue implicit invocation framework to ActionScript 3 and Flex.
Head over to the new Model-Glue Web Site to learn more!
Earlier today I asked Liz at Teratech if there was going to be a frameworks BOF at this year's CFUnited.
She replied that it's now scheduled for 9PM Wednesday night, location to be determined. I'll be showing Model-Glue 2.0 and Model-Glue:Flex, and I'd like to welcome anyone who either authors a framework to demo a bit of what they're up to, and I'd especially like invite anyone who uses ColdFusion to speak a bit about their experiences. Please comment if you'd like to be involved!
I've floated a few .zips of Model-Glue:Flex around, and so far, so good. However, one person who's not currently doing much Flex development had what I feel will be a key piece of feedback: the early zip did a lot to implement implicit invocation and the friendliness of Model-Glue, but it did nothing to remove the boilerplate that often goes along with writing a Cairngorm application that uses a service layer.
The Problem
A lot of Flex developers, myself included, use Business Delegates to separate the implementation of server-side services from the rest of our application.
Big term, easy concept: the delegate just wraps all the functions of the service.
Then, when we want to call the server, a Command calls the method on the delegate, stating that the Command should be used as the responder.
This means that any time I'd like to work with a new server-side operation, I've got a few things that are going to either slow me down or mess me up:
-
I've got to add boilerplate to the delegate:
public function doSomething():void {
var token:AsyncToken = service.listDynamicStrings();
token.addResponder(command);
}
-
I've got to implement responder functions:
public function result(data:Object):void { }
public function fault(data:Object):void { }
- If, for some reason (rare, but I've hit it), I need to make two server-side requests in one command, I've got to monkey about with responder delegates to get them to call different methods in the command.
While it's not *that* much code to write, when you stack it on top of creating the Command class (which is really not much but a procedural script), an Event class, and having to relate the two in the Controller, there's a lot of typing to be done.
So, my earlier reviewer basically said "Can you get rid of the yuck? Maybe you could write a dynamic proxy, handling methods not being found, that'd wrap a service and let you assign result/fault functions?"
Model-Glue:Flex's Solution
Ugly terms like AsynchronousMethodProxy aside, I've cooked up something that has a real feel of Model-Glue "easiness" to it - it's a little loosely typed, but darned easy to use.
The "autoproxy" lets you ask for any AbstractService (like a RemoteObject tag) in your ServiceLocator and make arbitrary method calls, using the name of the server-side function (e.g., <cffunction>). You just pass it whatever arguments the function requires, an optional result function, and then an optional fault functions. It's a lot like prototype's style of making Ajax calls.
Ok, code works better than words. This is all you have to do to ask for a list of contacts and use it as the source of an ArrayCollection in a model locator:
private var service:AbstractService = getService("contactService");
private var model:ModelLocator = ModelLocator.getInstance();
// Listener function in controller
public function listContacts(e:ModelGlueEvent):void {
service.list (
function(data:Object):void {
model.contacts.source = data.result as Array;
}
)
}
Let's spice it up and add a filter string as an argument and a reference to a common fault function:
public function listContacts(event:ModelGlueEvent):void {
service.list (
event.getValue("searchString"),
function(data:Object):void {
model.contacts.source = data.result as Array;
},
this.serverError
)
}
private function serverError(data:Object) {
Alert.show("Oops!");
}
Any takers, thoughts, flames?

