MG: Flex - Better Delegates and Putting Responders in Their Place

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.

[More]

Model-Glue: ColdFusion and Model-Glue: Flex released!

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!

CFUnited: Frameworks BOF Wednesday Night!

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!

Model-Glue:Flex Service Autoproxies

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:

  1. I've got to add boilerplate to the delegate:

    public function doSomething():void {

    var token:AsyncToken = service.listDynamicStrings();

    token.addResponder(command);

    }

  2. I've got to implement responder functions:

    public function result(data:Object):void { }

    public function fault(data:Object):void { }

  3. 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:

// In controller
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:

// Listener function in controller

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?

© 2008 Firemoss, LLC
BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.