Welcome!

Adobe Flex Authors: Jonny Defh, Pat Romanski, Liz McMillan, Rob Rusher, Aditya Banerjee

Related Topics: Adobe Flex

Adobe Flex: Article

Designing Loosely Coupled Flex 2 Components

Powerful tools

Flex 2 applications may have complex architectures and they are usually made up of multiple files: MXML, Actionscript and CSS.

Coding the entire application within a single file is not a best practise. It makes the code harder to maintain and reuse and the application is not architected into a logically pieces.

Flex 2 allows developers to break into small external pieces the project, creating separated MXML files and maintain them separately. The process of dividing Flex application into logic modules has many benefits. It allows the developer team to work and debug a single module independently, isolating errors and functionality of applications. It makes the code easier to maintain and reuse across multiple applications.

Each MXML file is an MXML component but only the main MXML application can load external MXML components. In fact only one Application tag can exist for a single application, everything else is MXML components.

In order to design MXML components you create a MXML file where the root tag is not an Application tag but it's a component tag (such as Vbox, Panel, Canvas, Button, Datagrid, etc.) with the declaration of the http://www.adobe.com/2006/mxml namespace.

The following code shows a simple MXML component, named custDataGrid.mxml, that is made up of a Datagrid to store data :

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:DataGrid id="myDG" >
<mx:columns>
    <mx:DataGridColumn headerText="Posts" dataField="title" />
<mx:DataGridColumn headerText="Date" dataField="pubDate" width="100" />
    </mx:columns>
</mx:DataGrid>

</mx:VBox>

The root tag is a simple Vbox component where the xmlns:mx="http://www.adobe.com/2006/mxml" is declared. Once created external modules, the main application invokes the MXML component as the following example :

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:cust="comp.*" >
<mx:Panel title="Comtaste's Blog Reader">

<cust: custDataGrid width="80%" />

</mx:Panel>

</mx:Application>

The main application adds a new XML namespace and uses a package name to represent all the components defined in a folder :

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:cust="comp.*" >

The "cust" namespace refers to MXML components into the "comp" folder, in fact as a best practise all components should be stored in a subdirectory

Component invocation is the same as with any other MXML tag, the only difference being the customized prefix rather than "mx" :

<cust: custDataGrid width="80%" />

Note that the MXML tag name corresponds to the component's filename.

Tightly coupled versus loosely coupled component
To make components configurable and reusable throughout your applications, you might want to create MXML components that accept properties, launch methods and dispatch events. To achieve this, components must not depend on a specific application (tightly coupled component), their variable's name or tag instance's name. In this scenario if the code of the application or the component changes, reliant code won't work anymore and we'll have to modify the tightly coupled component to reflect that change.

A much cleaner and better approach is to develop a loosely coupled component that dispatches the events to propagate return data to the application and contains property declarations for passing information to it.

This approach allows to create MXML components as "black boxes" with the following benefits :

  • They are easier to reuse and maintain
  • They don't know nothing about any other components' inner workings
  • They are not dependent on a variable's name and tag instance's name
As we said, in order to create a loosely coupled component we need properties to store information and an event model to dispatch events that contain the return data.

Properties are usually defined with Actionscript (although you can define them with MXML) and placed within a <mx:Script> block :

<mx:Script>
    <![CDATA[
       import mx.collections.ArrayCollection;

       [Bindable]
       public var lista:ArrayCollection;
    ]]>
</mx:Script>

The same is for methods of MXML components :

<mx:Script>
   <![CDATA[
      import mx.collections.ArrayCollection;

      [Bindable]
      public var lista:ArrayCollection;

      public function justWrite():String
      {
         return "This is a method of the component";
      }
   ]]>
</mx:Script>

In the following example the component defines a property that represents the dataprovider that will populate the Datagrid and a method that returns a string. This is the entire code for the custDataGrid.mxml file :

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script>
   <![CDATA[
      import mx.collections.ArrayCollection;

      [Bindable]
      public var lista:ArrayCollection;

      public function justWrite():String
      {
        return "This is a method of the component";
      }
   ]]>
</mx:Script>

<mx:DataGrid id="myDG" dataProvider="{lista}" >

</mx:DataGrid>

</mx:VBox>

NOTE FROM FLEX 2 LIVEDOCS : A public variable declaration or a set function in an <mx:Script> tag becomes a property of the component. A public ActionScript function in an <mx:Script> tag becomes a method of the component.

We can access to the component's methods or pass data to component's properties from the main application file :

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:cust="*">
<mx:Script>
   <![CDATA[
      import mx.collections.ArrayCollection;
      [Bindable]
      public var myData:ArrayCollection = new ArrayCollection (
      [{A:2000},{A:3000},{A:4000},{A:4000},{A:3000},{A:2000},{A:6000}]);

   ]]>
</mx:Script>
<cust:custDataGrid id="custDG" x="258" y="89" lista="{myData}"/>

<mx:Label text="{custDG.justWrite()}" x="300" y="44"/>
   </mx:Application>

In the main application we populate an ArrayCollection variable named "myData" and we pass it within the MXML component tag declaration through the following line of code :

<cust:custDataGrid id="custDG" x="258" y="89" lista="{myData}"/>


More Stories By Marco Casario

Marco Casario is CEO of Comtaste, a company devoted to develop Rich Internet Applications on the Web and for mobile devices.

He collaborates intensively with Adobe Italy as a speaker at conferences and as a consultant for Flash, Flex, and Flash Lite.

Learn more about Marco Casario at his blog http://casario.blogs.com. In 2005, Marco has founded Comtaste, a company dedicated to exploring new frontiers in Rich Internet Applications and the convergence between the web and the world of mobile devices — MobyMobile and YouThru are representative of their recent work. He is founder of the biggest worldwide Flash Lite User Group and of www.augitaly.com, a reference point for the Italian community of Adobe users, in which he carries out the role of Channel Manager for the section dedicated to Flex.

Comments (1) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
saravanan 11/23/07 12:44:26 AM EST

HI,

this is exellent tutorials..i have learned lot about using custom events in MXML and AS

But one more thing there is no change event for datagrid please check it , use some valid event for that ..