Archive for the ‘ flex ’ Category

Flex Frameworks: You Now Have Options

The Good Old Days

Remember when FuseBox came out for the ColdFusion community? Wow, it was great. Finally, we had a professionally developed code framework that was being adopted by people and companies worldwide. It showed even basic developers how code organization, standards, and design patterns could help them make a better product, and even help them professionally.

Based on that success, other brilliant people started creating, or porting, other successful frameworks for ColdFusion. We now have a good variety of very well-made frameworks from which to choose when starting a project. In fact, some of the “high brow” developers in our community now poo-poo Fusebox as something for beginners (I am not one of those), and Fusebox now takes somewhat of a back seat to some of the more advanced and intricate frameworks in many development shops now.

This is not Fusebox for Flex

In my mind, this is how I see the future for the Flex world as well. Right now, Cairngorm is the 400-pound gorilla in the community - not only because it was the first major player in the market, but is also backed by Adobe Consulting - and I expect it is being used by the majority of Flex development shops out there. Cairngorm is a great architecture and was developed using solid, industry-proven design patterns. However, as with most thing in the technology world, it has some weaknesses and drawbacks (though many of them have been “resolved” with extensions to the architecture).

Now, I’m not saying that Cairngorm will suffer the fate of Fusebox, but I think there will be some parallels in that the Cairngorm adoption rate will slowly reduce as other players enter the market with viable alternatives.

If you are currently in the process of evaluating Flex for your shop, or have already moving forward with Flex and are looking for a common framework or architecture on which you can build your applications, you now have some options other than Cairngorm.

Take some time to evaluate these projects and see which one fits your team, your business processes, and development lifecycles.

Flex Frameworks: Mate Review

Well I’ve finally reached a point in my latest AIR application where I can write up a useful review of the framework I chose to use: Mate.

In my continuing effort to avoid Cairngorm, I’ve been evaluating other Flex frameworks that are lightweight, rapid and comprehensible. In the application previous to this, I implemented PureMVC, and while I did not get to use all of the features, I did think it was a greater balance of ease and power than is Cairngorm, but was still rigid on implementation.

Less Regulation

For me, the purpose of any design framework is to enforce some standard patterns to create a scalable, flexible application, while allowing the actual implementation up to the developer and architect. Cairngorm does not fit this idea, and PureMVC came close, but still heavily regulated how the application was structured and implemented.

Mate, on the other hand, simply provides the mechanisms for enforcing a design pattern, while allowing more creativity and flexibility on how to implement it. Foremost to this is its use of the native event model in Actionscript for handling the application behavior. The tags provided by Mate simply add a layer of abstraction on top of this system that makes it both more powerful and more flexible (not to mention easier to learn).

Another concept that I found attractive is that you can break up your application into very granular pieces when you are creating a large project, but also have the ability to combine aspects together for a small application with only a handful of views and events.

Want to combine your event handlers and property injectors into the same file? No problem. They even provide different examples on their site that shows different implementation styles.

Tag Based Abstraction

I can’t gush enough about the tags available in Mate. Again, another benchmark for me on a valuable framework is how much menial coding it does for me. Hmm, that sounds familiar to another tag-based technology that I enjoy so much. What was that called again?

How do you get objects returned from a RemoteObject call injected into the view? It can’t be much more simple than this:

<Injectors target="{MyModel}">
   <PropertyInjector source="{MyEmployeeManager}" sourceKey="employees" targetKey="arrEmployees" />
   <PropertyInjector source="{MyProjectManager}" sourceKey="projects" targetKey="arrDivisionProjects" />
   <PropertyInjector source="{MyResourceManager}" sourceKey="resources" targetKey="arrPhysicalResources" />
</Injectors>

How about event handlers? It makes it real easy to find what you’re looking for when you have a tag named EventHandlers with child tags called RemoteObjectInvoker and MethodInvoker.

<EventHandlers type="{EmployeeEvent.GET_ALL}">

   <RemoteObjectInvoker ...>
      <resultHandlers>
         <MethodInvoker generator="{MyEmployeeManager}"
                  method="handleResponse"
                  arguments="{resultObject}"/>
      </resultHandlers>
   </RemoteObjectInvoker>

</EventHandlers>

Less Code!

Ever seen a Hello World example written using Cairngorm? I have and it’s not pretty. I even wrote up a demo on our internal Wiki for a Hello World application using PureMVC. It wasn’t much prettier. It required 12 steps to explain all the mechanisms involved.

In Mate, the required code to get a remote “Hello World!” string and display it in a view in almost laughably simple in comparison. They have a view injection diagram on their site that is a nice representation of how it works in the Mate framework.

Give Mate a try

In case the tone of my opinions in this article wasn’t a giveaway, I am a fan of Mate. It’s definitely something I’m going to keep evaluating for our future applications. I still have one more framework to look at - Swiz - which a colleague of mine has already starting investigating. What he has shown me so far is also impressive.

All in all, I’m glad that there are now frameworks out there that deliver on the promise of power and flexibility instead of just power.

The Value Objects

Otherwise known as a transfer object is simply a design pattern for exchanging data between disparate systems. I’m working on a application with a Flex UI and a ColdFusion backend, and I initially discovered that if I return a query directly to Flex, it is converted into an ArrayCollection populated with simple Objects.

What I wanted was an array of specifically typed objects that I could cast as value objects in Flex. Here’s a very simplistic example of an Employee value object in Flex. It has two properties:

  • Employee ID
  • Employee Name

Flex Employee Value Object

package net.fusioncube.transferObjects
{
   [RemoteClass(alias="net.fusioncube.model.employee.Employee")]
   [Bindable]
   public class Employee
   {
      private var _employeeID:uint;
      private var _employeeName:String;

      /* constructor */
      public function Effort(employee_id:uint = 0,
                  employee_name:String = "")
      {
         this._employeeID= employee_id;
         this._employeeName= employee_name;
      }

        public function get employee_id():uint
        {
        	return _employeeID;
        }

        public function set employee_id(value:uint):void
        {
        	if(value != 0) _employeeID= value;
        }

        public function get employee_name():String
        {
        	return _employeeName;
        }

        public function set employee_name(value:String):void
        {
        	if(value != "") _employeeName= value;
        }
   }
}

You may have noticed the RemoteClass metadata applied to the Actionscript class. What this does is ensure that this Flex class maps directly to a ColdFusion component value object. To make a ColdFusion component value object is simple: you use the <cfproperty> tag for each property and specify each one’s type.

In this example, I’ve also added an init() method, whose use we’ll discover later.

ColdFusion Employee Value Object

<cfcomponent displayname="Employee" output="false">
   <cfproperty name="employee_id" type="numeric" default="" />
   <cfproperty name="employee_name" type="string" default="" />

   <cffunction name="init" access="public" returntype="net.fusioncube.model.employee.Employee" output="false">
      <cfargument name="employee_id" type="numeric" required="false"  />
      <cfargument name="employee_name" type="string" required="false"  /> 

      <cfset this['effort_id']       = arguments.effort_id />
      <cfset this['employee_name']      = arguments.employee_name />

      <cfreturn this />
   </cffunction>

</cfcomponent>

Converting a Query to an Employee Array

Again, as a very simple example, let’s say I have an EmployeeService component in my service layer and have a method listEmployees() that simply queries the employees table and returns all rows.

<cffunction name="listEmployees" access="public" output="false" returntype="query">
   <cfset var effortQuery = "" />

   <cfquery datasource="#variables.config.getSetting("datasource")#" name="employeeQuery">
   select e.* from employees e
   </cfquery>

   <cfreturn effortQuery />
</cffunction>

Since I don’t want to return a query, and I certainly don’t want to have two methods in every single component - one that returns a query and one that returns an array of objects - I use the handy, dandy AOP feature in ColdSpring to apply an advice that does it at runtime.

QueryToVOAdvice Advice

In this advice, I simply loop over the query’s rows and columns to create a simple structure containing the key/value pairs for each row. It then creates a new component for each query row by passing that structure to the init() function - which you saw above - and adds it to an array.

The result is an array of Employee-typed objects.

<cfcomponent displayname="QueryToVOAdvice" extends="coldspring.aop.MethodInterceptor">

   <cffunction name="init" returntype="utility.aop.advice.converters.QueryToVOAdvice" access="public" output="false">
      <cfreturn this />
   </cffunction>

   <cffunction name="invokeMethod" access="public" returntype="any">
      <cfargument name="methodInvocation" type="coldspring.aop.MethodInvocation" required="false" />

      <cfscript>
      var local = structNew();
      local.queryRow = 1;

      // Create an array to hold the value objects
      local.valueObjectArray = ArrayNew(1);

      // Store the resulting query object from the method execution
      local.queryObject = arguments.methodInvocation.proceed();

      // Loop over the query rows
      for(local.queryRow=1; local.queryRow lte local.queryObject.recordCount; local.queryRow = local.queryRow+1)
      {
         local.voStruct = structNew();

         // Loop over the query columns and create a key/value pair for each value
         // in this row of the query
         for(local.columnNum=1; local.columnNum lte listLen(local.queryObject.columnList); local.columnNum = local.columnNum+1)
         {
            local.columnName = listGetAt(local.queryObject.columnList, local.columnNum);
            local.voStruct[local.columnName] = local.queryObject[local.columnName][local.queryRow];
         }

         // Create an instance of the value object (obtained from the getValueObject method)
         // initializing it with the structure we created.  Add the value object to the array.
         arrayAppend(local.valueObjectArray, createObject('component', arguments.methodInvocation.getTarget().getValueObject()).init(argumentCollection=local.voStruct));
      }

      return local.valueObjectArray;
      </cfscript>
   </cffunction>

</cfcomponent>

ValueObject Property

For each of my beans, in this case the Employee bean, I can simply apply an advice in the definition. For this to work, I create a valueObject property in each component.

<component name="Employee">
   <cffunction name="setValueObject" access="public" output="false" returntype="void">
      <cfargument name="valueObject" type="string" required="true" />
      <cfset variables.valueObject = arguments.valueObject />
   </cffunction>

   <cffunction name="getValueObject" access="public" output="false" returntype="string">
      <cfreturn variables.valueObject />
   </cffunction>
</component>

Employee Bean Definition

Now when I define my Employee bean, I specify the type of the value object (the type that gets returned from the init() function), and then apply the advisor (shown below).

<bean id="Employee" class="coldspring.aop.framework.ProxyFactoryBean">
   <property name="target">
      <bean class="net.fusioncube.model.employee.EmployeeService">
         <property name="valueObject">
            <value>net.fusioncube.model.employee.Employee</value>
         </property>
      </bean>
   </property>
   <property name="interceptorNames">
      <list>
         <value>queryToValueObjectAdvisor</value>
      </list>
   </property>
</bean>

QueryToValueObjectAdvisor Definition

<bean id="queryToValueObjectAdvisor" class="coldspring.aop.support.RegexMethodPointcutAdvisor">
   <property name="advice">
      <bean class="utility.aop.advice.converters.QueryToVOAdvice"/>
   </property>
   <property name="pattern">
      <value>^list.*$</value>
   </property>
</bean>

The Flex Array of Typed Objects

Here’s an image of an example array I get back from ColdFusion in one of my current apps. You can see that each object was automatically converted into a Teammate (equivalent of an Employee) rather than a simple Object.

Caveat: If you’re passing back queries with a thousand or more rows, and are running CFMX 7 or older, then this solution may cause serious performance problems as object creation is notoriously “slow” in those versions of ColdFusion.

Flex 3.1.0 Update Hack

When updating the Flex Builder to the 3.1.0 SDK, the source code for the data visualization and advanced data grid aren’t updated correctly. To fix this in Windows, follow these steps:

  1. Help Menu > Search for flex builder update
  2. Copy the license.properties file from C:\Documents and Settings\All Users\Application Data\Adobe\Flex to C:\Program Files\Adobe\Flex Builder 3\sdks\3.1.0\lib
  3. Create a batch file in the C:\Program Files\Adobe\Flex Builder 3\sdks\3.1.0\lib folder and place the following command in it: java -jar .\DMV-source.jar .\ ..\
  4. Run the batch file
  5. Build the next killer Flex app

Selecting weeks in Flex DateChooser control

When a user clicks on any day within a DateChooser controller and you want to automatically select every day for that week, you can use the selectedRanges property of the control. This is easy adaptable to selecting months or any custom range.

Define some time constants

private static const millisecondsPerMinute:int = 1000 * 60;
private static const millisecondsPerHour:int = 1000 * 60 * 60;
private static const millisecondsPerDay:int = 1000 * 60 * 60 * 24;

Add a DateChooser control

<mx:DateChooser id="calendar" x="0.5" y="76" width="205"
		showToday="false"
		enabled="false"
		change="calendarClickHandler(event)" />

Set the selectedRanges property

private function calendarClickHandler(event:CalendarLayoutChangeEvent):void
{
	var selectedRanges:Array = new Array();
	var selectRange:Object = new Object();
	var rangeStart:Date = new Date(event.newDate.getTime() - (millisecondsPerDay * event.newDate.day));
	var rangeEnd:Date = new Date(rangeStart.getTime() + (millisecondsPerDay * 6));

	selectRange.rangeStart = rangeStart;
	selectRange.rangeEnd = rangeEnd;
	selectedRanges.push(selectRange);

	calendar.selectedRanges = selectedRanges;
}