auto control enabling and disabling on services called added to trunk

The CommandInfo class has had two additional properites added: objectToEnableOnFault and objectToEnableOnResult. With these you can disable controls that activate events inside their events so a user cannot click the control twice (or technically and entire window or pane) while it is still processing. So inside my handleEvent the first thing I do is say: target.enabled = false (you can also explicity list the control you want to disable with context.mycontrol.enabled = false, but using the control that dispatched the event is cleaner) then before each service call I use code like: var info:MVCServiceInfo = new MVCServiceInfo; info.objectToEnableOnFault = target; That way if an error occurs, gemvc will automatically re-enable the control so you don't have to worry about it. You can also set info.objectToEnableOnResult = target if you want your control automatically re-enabled because your event is complete. Otherwise you add the line at the end of your event before your last service call. Sometimes you may have to set target.enabled = true yourself at the end of your event as well if you have a case where based upon on a condition you call a service or you just exit. I have seen in my applications where if you select GUI controls too fast errors can result. This is most critical with events that update the db but I have also used it on selection events that change the screen (like filters) because these can cause errors as well if you select them too quick. In order for target.enabled to work you need to make sure that the control you want to disable dispatches the event. Currently, in a combo box, for example, you just say click="dispatchEvent(..)" but now you should say comboboxid.dispatchEvent(...) otherwise you will get the enclosing UIComponent (Canvas, Pane, VBox, etc.) as the target (which is some cases may be a good thing as it is in mine).

Logging support added to GEMVC trunk

I have not created an official release (one is coming very soon just trying to get a demo application created) but there are new features in the gemvc trunk that may be of interest.

1) The messaging.xml and services.xml have been combined into one file. Your entries will now look like:

<SERVICE ALIAS="ximlogger" SERVICEPATH="xim.services.XIMLoggingService" DESTINATION="ColdFusion" CLASSNAME="xim.as3.services.XIMLogger" />

<MESSAGESERVICE ALIAS="ximupdate" DESTINATION="ColdFusionGateway" />

2) Logging has been added.

With Flex there is no way to globally catch errors. You have to manually put try/catch blocks everywhere. GEMVC has been modified to help with this by catching any errors that occur in a service call handler (unless you use callLater()). It will display the standard GEMVC alert box (or the one you overrode MVCApplication with) and will log it back to the server if you have a logging Service. If your logger supports mail you can mail them as well.

All you have to do to take advantage of this feature is:

a) Have a CF logging service that has a log function that accepts a string message and int logLevel.

b) Add this to your services.xml file:

<SERVICE ALIAS="ximlogger" SERVICEPATH="xim.services.XIMLoggingService" DESTINATION="ColdFusion" CLASSNAME="xim.as3.services.XIMLogger" />

<LOGGINGSERVICE ALIAS="log" SERVICE="ximlogger" ENDPOINT="ximLog" />

<LOGGINGSERVICE ALIAS="logMail" SERVICE="ximlogger" ENDPOINT="ximMail" />

Notice that you can have multiple loggers.

You may want to overload the getInfoLogLevel and getErrorLogLevel methods if the GEMVC defaults do not match your log levels (currently 4 and 1 respectively).

More to come

Call for volunteers to create SOAPGateway

I am been pretty focused on use the Flex RemoteObject tag and the AMF protocol that I have neglected the WebService tag. If anyone out there is trying to use SOAP or has the time I would greatly appreciate a WebServiceGateway to complement the AMFGateway and MessagingGateway classes. Anyone up for it?

Minor update to SVN trunk for Services Null on Initialization

In the documentation it states that you should perform the following to initialize your application:

public function init():void { // set up our MVC controller for this component addEventListener(MVCServicesInitializedEvent.MVC_SERVICES_INITIALIZED,servicesInit); controller = new MyController(this); if (getService() != null) { dispatchEvent(new MyInitEvent()); } } private function servicesInit(ev:Event):void { dispatchEvent(new MyInitEvent()); } Turns out that if you do not use the optional messaging.xml file then the MVCServicesInitializedEvent is not thrown and due to timing your services may be null. I updated the trunk to fix this or you can just create an empty messaging.xml file.

GEMVC 1.1 released

This is the distribution that includes a new tutorial submitted by Gabe Iverson and includes the new features that have already been blogged about. Hierarchical controllers are supported and Flex producer/consumer tags are encapsulated by the service layer. Next up is allow a controller to perform an action from an event instead of the event's handle function (which will still be allowed). This will satisfy the MVC purists. Also, more mxml tag support is planned.

Initializing your app

Depending upon timing in your flex app there is a possibility of your creationComplete=init() method executing and dispatching an event that uses the service layer before the service layer has been initialized. To handle this situation you need to use the MVCServicesInitializedEvent that is thrown by the framework like so:

public function init():void { // set up our MVC controller for this component addEventListener( MVCServicesInitializedEvent.MVC_SERVICES_INITIALIZED, servicesInit); controller = new MyAppController(this); if (getService() != null) { dispatchEvent(new MyAppInitEvent()); } } private function servicesInit(ev:Event):void { dispatchEvent(new MyAppInitEvent()); }

GEMVC used at NASA - Let me know if you are Using GEMVC!

GEMVC is being used for several projects at the Johnson Space Center. These include the Altair Lunar Lander Infomation Model tool suite (comprised of 5 Flex tools), the Stardust Sample Management Suite for the Astromaterials division, and the Project Management Toolkit for the Engineering Science Contract of the JSC Engineering Directorate.

Let me know where you are using it!

Thanks.

Additional functionality now in SVN trunk (messaging and hierarchical controllers)

I haven't had a chance to formally update the docs and issue a release but there are two new capabilities in the SVN trunk: One, you can now have multiple controllers respond to the same event (still working on controllers executing the code themselves instead of the event as an option) and two, the LiveCycle Data Services publish and subscribe APIs are now wrapped in the service layer like the remoting services (not much new functionality here, just done to be consistent). I added this so the ColdFusion backend service layer could send change events to the Flex apps.

To use the multiple controllers, your events now get a controllerId parameter (all your current events will have to add this parameter..sorry) so you can decide which action to take based upon which controller is handling the event. The controller id is now an optional parameter in the controller constructor. For example:

public void handleEvent(context:Object,controllerId:String="") { if (controllerId == 'MAIN') { Do blah; } else if (controllerId == 'SubController') { Do something else; } }

The publish and subscribe functionality mirrors the producer and consumer Flex objects. Below is a subscribe example, publish is similar:

public var consumer:Consumer=null;

public function subscribe():void { var service:MVCMessagingService = YourApplication(Application.application).getMessageService(); if (service != null) { consumer = service.subscribe(somethingChanged); } }

private function somethingChanged(ev:MessageEvent):void { trace('Got update: '+ ev.message.body.MESSAGE); }

The service information is in config/messaging.xml (rename if you want to deactiviate it) as looks like this:

The Destination is an empty gateway set up in the CF administrator. Unless you grabbing messages from the CF side all you need is an empty cfc in your services layer:

Under event gateways| gateway instances add a new gateway with the following info:

Gateway ID: MyGateway

Gateway Type: DataServicesMessaging

CFC Path: C:\Inetpub\wwwroot\llds\services\MessagingGateway.cfc

Configuration File: C:\Inetpub\wwwroot\llds\services\gateway.cfg

Startup Mode: Automatic

MessagingGateway.cfc:

cfcomponent output="false">

gateway.cfg:

# # Flex event gateway configuration #

# don't need anything when integrated with CF

# This is the destination of the mssages #destination=ColdFusion

#host=127.0.0.1

Event Reuse

There are times where you need one event to perform the behavior of another event you already have. In this case you have two choices: One, called context.dispatchEvent from your event handler and throw the new GEMVC Event or two, inherit from a base event, overriding the behavior where necessary. While case one is probably the cleaner way in terms of decoupling and is what is used when you want a higher level controller to handle a portion of an event a lower controller is handling, sometimes due to asynchronous nature of Flex you need to perform an action immediately before do anything else. In this case you just need to inherit the event you want to share and override its handleEvent method or any other methods it may have. You can then substitute your own handlers if the you make service layer calls. Since it is impossible to guess at what events someone may want to extend it is a good idea to code your GEMVC Events in such as way as they can be easily extended. This means that your variables and methods should be in the protected scope and your constructor should be designed to accept any event type string. The following code snippet shows how to set up your constructor:

public class ResetSelectedNodeEvent extends Event implements MVCEvent

{

public static const RESET_SELECTED_NODE:String = "RESETSELECTEDNODE";

protected var _pane:String;

protected var globalApp:MELApplication = MELApplication(Application.application);

protected var model:MELModel = MELModel(MELApplication(Application.application).model);

public function ResetSelectedNodeEvent(pane:String='',type:String=RESET_SELECTED_NODE):void

{

super(type, true, false);

_pane = pane;

}

By adding a type parameter, an extended event can supply its own event identifier but since it is optional, users of the base event do not have to change anything.

GEMVC 1.0.1 released

GEMVC has been updated with support for encapsulating Flex Producer and Consumer tags within the service layer like the remoting tag. It doesn't really add any functionality beyond what the tags themselves provide but does make it consistent and allow you to specify the connection information in a messaging.xml configuration file. See the updated documentation for more information.

New Versioning

Due to some additional features, the versions will now be:

1.0.5 - Support for messaging services that use the Consumer and Producer tags (this is actually in subversion now I just have not officially released it and updated the docs)

1.1 - What was the 1.0.5 release

1.5 - What was the 1.1 release

More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.5.006. | Protected by Akismet | Blog with WordPress