So you wanna build a Flex application - Part 2- Main Application File

In our series on Surfing Stats, we have covered the intent and the directory structure. (download the code using the download link at the bottom of the Intro to Surfing Stats post) We will now cover the main application file. It is important to note Surfing Stats does not use a framework. Frameworks are powerful code organization tools that contribute to rapid development and maintainability. Since the goal of Surfing Stats is to teach development of a simple application in 4 hours, I made the decision to avoid discussing or implementing any framework. After all, if you do not have the skills to build an application without using a framework, you probably do not have any business using a framework to build an application.

Our application is driven by a main application file titled Main.mxml. Since MXML is really shorthand for working with ActionScript classes the Flex Framework will actually generate an ActionScript class using your MXML file as a template. ActionScript classes should always be given an uppercase name thus we give the MXML file an uppercase name. I like to use Main.mxml to designate the main file in the application. Note the first MXML tag used is the Application tag.

The Main.mxml file serves 3 purposes:

  1. Application Configuration
  2. Shared Variables/Bindings Initialization
  3. Program Flow Control
Let us examine each in turn.

Application Configuration

The Surfing Stats application has a css file configured to provide visual configuration. The CSS file is linked as follows:

view plain print about
1<mx:Style source="css/global.css" />
Also configured is a base URL that defines the main endpoint for our XML service and a definition of the available datasets (the ChartConfig object). Lastly, we define a base vertical layout using a VBox, containing a header image, a tab bar and a custom component called Chart Toggle.

Shared Variables/Bindings Initialization

Flex applications maintain state. In Surfing Stats, we maintain the Selected Dataset and the Selected Dataset ArrayCollection. These variables are created in Main.mxml and shared amongst the respective child components.

Program Flow Control

Our program loads XML data representing a specific category then visually represents the data in table, bar chart and pie chart format (if available). When the application is initialized, the Flex framework runs a creationComplete event. In the definition of the Application tag we set the custom function initFunc to execute. The initFunc creates the ChartConfig object then uses the ChartConfig data to configure the tab bar of datasets. Finally, initFunc fires off the HTTPService request for the initial dataset from the server.

When the server response is complete, the xmlDataHandler function executes, parsing and loading the XML string data into an ArrayCollection marked Bindable, then performing a numeric sort.

Lastly, the Main.mxml file contains the function, datasetSelected, responsible for processing the user click on a specific tab.

The Main.mxml file is the highest level component in our Surfing Stats application. By only keeping the highest level configuration, initialization and program flow, we keep our application readable and easily understood.

view plain print about
1<?xml version="1.0" encoding="utf-8"?>
2<mx:Application
3    xmlns:mx="http://www.adobe.com/2006/mxml"
4    xmlns:c="components.*"
5 layout="vertical"
6 backgroundColor="white"
7 creationComplete="initFunc()"
>

8     <mx:Style source="css/global.css" />
9        <mx:Script>
10            <![CDATA[
11                // Flex Framework Imports
12
                import mx.collections.ArrayCollection;
13                import mx.collections.Sort;
14                import mx.collections.SortField;
15                import mx.events.ItemClickEvent;
16                import mx.rpc.events.ResultEvent;
17                
18                //Project specific imports
19
                import data.ChartConfig;
20                import vo.Dataset;
21                
22                //Bindings
23
                [Bindable] public var datasetAC:ArrayCollection;
24                [Bindable] public var selectedDataset:Dataset = new Dataset("","");
25                [Bindable] public var selectedDatasetAC:ArrayCollection = new ArrayCollection();                
26                //Configuraton
27
                private var baseURL:String = "http://www.nodans.com/custom/surfingstats/statsexport.cfm?dataset=";
28
                //private var baseURL:String = "http://localhost/360Atlanta/xml/";
29
                //Application Start function
30
                public function initFunc():void{
31                    //datasetAC holds configured datasets
32
                    datasetAC = new ChartConfig(baseURL);
33                    //Configure tabBar
34
                    tabBar.dataProvider = datasetAC;
35                    tabBar.labelField ="
title";
36                    //initialize selectedDataset
37
                    selectedDataset = datasetAC[0];
38                    tabBar.selectedIndex = 0;
39                    //process
40
                    processDataset();
41                }                
42            private function xmlDataHandler(event:ResultEvent):void
43            {
44                //the XML is Converted to an Array Collection by the result event
45
                selectedDatasetAC = event.result.query.row;
46                //Define, configure amd run a numeric sort
47
                var sort:Sort = new Sort();
48                    sort.fields = [new SortField("
amount", false, false, true)];
49                    selectedDatasetAC.sort = sort;
50                    selectedDatasetAC.refresh();
51            }
52                        
53            private function datasetSelected(event:ItemClickEvent):void{
54 var targetComp:TabBar = TabBar(event.currentTarget);
55     //walk up the dataprovider to get the dataset object for the selected tab
56
selectedDataset = targetComp.dataProvider[event.index] as Dataset;
57 processDataset();
58            }
59            
60            private function processDataset():void{
61                //this is the endpoint for the data service
62
                xmlLoader.url = selectedDataset.source;
63                xmlLoader.send();            
64            }            
65            ]]>
66        </mx:Script>
67
68    <mx:HTTPService id="xmlLoader" result="xmlDataHandler(event)" />
        
69    
70 <mx:VBox horizontalAlign="center" >
    
71        <mx:Image source="@Embed('images/Header.png')" />

72        <mx:TabBar id="tabBar" itemClick="datasetSelected(event)" />
73        <mx:VBox>
74            <c:ChartToggle width="
700" height="450" selectedDataset="{selectedDataset}" selectedDatasetAC="{selectedDatasetAC}"/>
75        </mx:VBox>
76 </mx:VBox>
77</mx:Application>

There are no comments for this entry.

Add Comment Subscribe to Comments

1/2/08 1:53 PM # Posted By Matt Platte

<blockquote><em>...if you do not have the skills to build an application without using a framework</em></blockquote>

Nonsense. Here's what Adobe have to say: "Adobe® Flex™ 2 is a cross-platform development framework for creating rich Internet applications (RIAs)..."

Flex is a framework. 'Nuff said.

kthxbye


1/2/08 2:02 PM # Posted By Dan Wilson

Hey Matt,

Thanks for stopping by.

Clearly Flex is a framework. My goal is to teach students to build this application using the Flex framework. Leaving out the Flex framework would be sub-optimal, I am sure you would agree. Maybe I wasn't clear enough that by framework, I meant such frameworks as Cairngorm, EasyMVC, PureMVC and the host of other frameworks meant to be used in ADDITION TO the Flex framework.

I'll try to be more careful when using the word framework. I see now how some folks can be confused.

DW


1/2/08 2:26 PM # Posted By Joe Rinehart

Matt, Dan may have been vague, but I believe he's referring to an _architectural_ framework, which is a much different idea that what the Flex framework provides.

Flex is a framework, but it's more of a presentation and connectivity framework that anything else. As apps grow, the framework of Flex stops sufficing, and either non-framework implementations of something like MVC or the use of an architectural framework (that may or may not use MVC) becomes quite necessary.

Either way, Dan's comment is valid: if you can't write an app without an (architectural) framework, you shouldn't grab one off the shelf and try using one, as you probably haven't seen / experienced the problems that make them necessary.


1/2/08 2:32 PM # Posted By Simeon

I agree that flex has a framework, if you refer to http://www.adobe.com/products/flex/sdk/ and checkout the second paragraph you will find that the flex framework includes a library of classes for UI, event dispatching and data binding. It also mentions that these classes provide a head start.

A head start to what? To building RIAs. However anyone who has built an application with more than a couple components will concede that Adobe has provide the basis for the RIA application Architecture. However more complex design challenges can not be taken into account at that low a level. As such many Architectural Flex Frameworks have been developed to pick up where the core framework leaves off.

Building Flex applications with out the core framework is just flash. Building Flex applications with no architecture is just foolish. And Dan is showing those who are ready a good path to building well architected applications.


1/3/08 12:21 PM # Posted By Bruce

Dan - thanks for posting this example code and your explanations.

I like your use of custom components and the images.

I loaded your code in my Flex Builder and ran it locally. Of course I get the Flash security error when the HTTPService executes. Could you create a cross domain XML file to allow people outside your domain access to the CFM file that creates the XML? I'd like to run the app on my development machine and play around with your code to see how things are working.

If that's not possible, could you provide the CFM backend file? I could hook it up into my own BlogCFC version to get data for the Flex app.

Again thanks for sharing this code and your knowledge.


1/3/08 8:45 PM # Posted By Dan Wilson

@Bruce

Good point. I'd like to release the ColdFusion code at some point. After I wrote it, I figured out a way better integrate with BlogCFC and when I get a little extra time, I'll write and release that version.

So the application can be useful to you now, I've implemented a crossdomain.xml file. Being mindful of security, it only affects the directory: http://www.nodans.com/custom/surfingstats

So the off-root crossdomain.xml would be found I used the following line:         Security.loadPolicyFile("http://www.nodans.com/custom/surfingstats/crossdomain.xml");

This is the only source code change. You can either implement it in your copy of the source (I stuck it at Main.mxml line 28), or redownload from here:

http://www.nodans.com/index.cfm/2008/1/2/Introduci...

Let me know if I've munged anything.

DW


1/3/08 11:05 PM # Posted By Bruce

Dan - thanks for the extra work. I get the data now. I'm looking forward to more posts about how you built this application.


Add Comment Subscribe to Comments