Avg. Rating 4.9
Tags:



Problem

Create simple flex applications (prototypes) having simple and clear structure

Solution

Create a simple MVC skeleton to better organize your code.

Detailed explanation

  This weekend I tried to make an "Air" client for search using "Adobe Community Help. I had no prior experience with Flex and AIR. My first attempt ended as a simple project for college, a spaghetti code. All examples found on the web or official documentation are based on massive use mxml code. I ended up having a glorious mxml file. Huge  :-) .

Some smart guys are telling you to split your mxml using an ActionScript file but is like putting the trash under the carpet. It is still spaghetti code but in two dishes.

I tried to remember how I would have programmed it in Java Swing.  9 years have passed since then but I remembered.  TableModelDefaultListModelButtonModel etc. they all came out from a dark corner of my memory. Yes ! I remembered, Swing MVC.

A typical sample from documentation…..

<?xml version="1.0" encoding="utf-8"?>
 <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
     <mx:Panel x="10" y="10" width="350" height="200"
title="Rate Customer Service">
         <mx:ComboBox id="cbxRating" x="20" y="20"
width="100">
             <mx:dataProvider>
                 <mx:Array>
                     <mx:String>Satisfied</mx:String>
                     <mx:String>Neutral</mx:String>
                    
<mx:String>Dissatisfied</mx:String>
                 </mx:Array>
             </mx:dataProvider>
         </mx:ComboBox>
         <mx:Button x="140" y="20" label="Send"/>
    </mx:Panel>
 </mx:Application>
Who hard-codes his application in this way? In a typical application you get this stuff from files or database. But let's see the good part, at least is giving you a hint, a  ComboBox and  List are accepting an  Array as input.
 

MVC applied to Flex

First of all a briefing about MVC

  1. Model, is the data. Manipulates the internal state and fire events when the internal state changed.
  2. View, the visual representation for the Model's data (controls on the screen)
  3. Controller, is responsible for interpreting the user actions on the view and make changes to the model. (usually an event handler in flex)

In reality there is no 100% demarcation between these three layers. Is not that easy to make them completely decoupled and usually we end up making some tradeoffs.

The controller will always know about the view and the view about the controller. Controller also knows about the model. In the end I could say that the model is the only piece of the MVC that can be "100% decoupled".

Let's try to put a simple screen like this into MVC.

Create simple flex app demos having simple and clear structure

We fill in some text and then press Add. After we press add the text box is cleared and the text is added into de the list. In the end wee look into it and try to make a reusable component.

Model

The model contains the actual data, and for our example it should a class that hold list values. As I pointed out earlier we could use an ArrayCollection to store the list. For this we make an actionscript class named  ListModel

The view should display model's changes and for this we mark the model class as  [Bindable]. This is nice feature of ActionScript, no such thing in Java Swing.

Now, to add a new item in the list we simply nee an  addElement  function. In this example we make the model a singleton. This means that if we make more than one list they will share the same data.

package org.bserban.flex.simplemvc.model
 {
     import mx.collections.ArrayCollection;
     /**
     * Model class used to store list data and to
     * provide access to the list content.
     *
     * For demo purposes, we have only addElement.
     */
     [Bindable]
     public class ListModel
     {
         public var items :ArrayCollection = new ArrayCollection();
         private static var instance:ListModel;
         public function ListModel(){
             instance=this;
         }
         /**
          * For this demo we treat this class as singletone.
          * If list is reused the component that reuse it
          * must keep reference to model and controler.
          */
         public static function getInstance():ListModel{
             if(instance == null){
                 instance = new ListModel();
             }
             return instance;
         }

         /**
          * Add a new element to the list, the model is bindable,
          * no further actions are required, the view
          * is notified automatically.
          */
         public function addElement(itm:String): void{
             items.addItem(itm);
             trace(" item added, now we have:"+items.length);
         }
     }
 }

Controller

The controller is responsible for the interaction between view and model. In our case will make the validation of the text, it doesn't allow the view to add empty text into the list. Let's make a new class named  Controller. As an exercise add also a sort function.

The controller holds a reference to the model and provides functions to the view. In a more advanced implementation the Controller would listen for events from the view and the decides what action should do.

package org.bserban.flex.simplemvc.controller
{
import org.bserban.flex.simplemvc.model.ListModel 
import mx.utils.StringUtil;

 public class Controller{

 private var model:ListModel = ListModel.getInstance();
 /**
 * Glue the interaction between view and model.
 */
 public function Controller(){
 }
 /*** add a new item into the list model.*/
 public function addPerson(name:String):void{
   if(name==null || StringUtil.trim(name).length==0){
      trace("emptyname");
   }else{           
      model.addElement(name);
   }
 }
}
}  
  
 
  

View

The view is the graphical representation of the component. Usually it is a an mxml file but it can be also an actions script file for advanced programmers. It binds his data to the model and use the controller to process the view events. Let's name it  SimpleAirMVC.mxml. I added  Air to its name because i decided to make an air project in Flex Builder.

                <?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication
xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
height="226" width="235">
     <mx:Script>
         <![CDATA[
         import mx.controls.List;
         import org.bserban.flex.simplemvc.model.ListModel;
         import org.bserban.flex.simplemvc.controller.Controller;
         [Bindable]
         private var model:ListModel = ListModel.getInstance();
         private function clickHandler():void
             {
                 var controler:Controller = new Controller();
                 controler.addPerson(personTxt.text);
                 personTxt.text="";
             }
         ]]>
     </mx:Script>
     <mx:TextInput x="10" y="10" id="personTxt" text=""
width="145"/>
     <mx:Button x="163" y="10" label="Add" id="btnAdd"
click="clickHandler()"/>
     <mx:List x="10" y="40" width="218"
dataProvider="{model.items}"></mx:List>
</mx:WindowedApplication> 
 
 
  

This is a  simple way to implement a MVC in a small application. Things can become more complicated if the application is big. If this is the case then you should look over  Pure MVC framework or  Cairngorm. They eliminate the dependencies between MVC layer by using events. It is an event driven approach.

You may download the source code here  SimpleAirMVC


 
More articles here http://www.bserban.org


Cheers,


+
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

Report abuse

Related recipes