Simple MVC for Flex and AIR

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. TableModel, DefaultListModel, ButtonModel etc. they all came out from a dark corner of my memory. Yes ! I remembered, Swing MVC.

A typical sample from documentation…..

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
   3:     <mx:Panel x="10" y="10" width="350" height="200" title="Rate Customer Service">
   4:         <mx:ComboBox id="cbxRating" x="20" y="20" width="100">
   5:             <mx:dataProvider>
   6:                 <mx:Array>
   7:                     <mx:String>Satisfied</mx:String>
   8:                     <mx:String>Neutral</mx:String>
   9:                     <mx:String>Dissatisfied</mx:String>
  10:                 </mx:Array>
  11:             </mx:dataProvider>
  12:         </mx:ComboBox>
  13:         <mx:Button x="140" y="20" label="Send"/>
  14:     </mx:Panel>
  15: </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.

image

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.

   1: package org.bserban.flex.simplemvc.model
   2: {
   3:     import mx.collections.ArrayCollection;
   4:     /**
   5:     * Model class used to store list data and to
   6:     * provide access to the list content.
   7:     *
   8:     * For demo purposes, we have only addElement.
   9:      */
  10:     [Bindable]
  11:     public class ListModel
  12:     {
  13:         public var items :ArrayCollection = new ArrayCollection();
  14:         private static var instance:ListModel;
  15:         public function ListModel()
  16:         {
  17:             instance=this;
  18:         }
  19:         /**
  20:          * For this demo we treat this class as singletone.
  21:          * If list is reused the component that reuse it
  22:          * must keep reference to model and controler.
  23:          */
  24:         public static function getInstance():ListModel{
  25:             if(instance == null){
  26:                 instance = new ListModel();
  27:             }
  28:             return instance;
  29:         }
  30:         /**
  31:          * Add a new element to the list, the model is bindable,
  32:          * no further actions are required, the view
  33:          * is notified automatically.
  34:          */
  35:         public function addElement(itm:String): void{
  36:             items.addItem(itm);
  37:             trace(" item added, now we have:"+items.length);
  38:         }
  39:     }
  40: }

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.

   1: package org.bserban.flex.simplemvc.controller
   2: {
   3:     import org.bserban.flex.simplemvc.model.ListModel
   4:     import mx.utils.StringUtil;
   5:     public class Controller
   6:     {
   7:        private var model:ListModel = ListModel.getInstance();
   8:         /**
   9:          * Glue the interaction between view and model.
  10:          */
  11:         public function Controller(){
  12:         }
  13:         /**
  14:          * add a new item into the list model.
  15:          */
  16:         public function addPerson(name:String):void
  17:         {
  18:             if(name==null || StringUtil.trim(name).length==0){
  19:                 trace("empty name");
  20:             }
  21:             else{
  22:                 model.addElement(name);
  23:            }
  24:         }
  25:     }
  26: }

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.

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" height="226" width="235">
   3:     <mx:Script>
   4:         <![CDATA[
   5:         import mx.controls.List;
   6:         import org.bserban.flex.simplemvc.model.ListModel;
   7:         import org.bserban.flex.simplemvc.controller.Controller;
   8:
   9:         [Bindable]
  10:          private var model:ListModel = ListModel.getInstance();
  11:         private function clickHandler():void
  12:             {
  13:                 var controler:Controller = new Controller();
  14:                 controler.addPerson(personTxt.text);
  15:                 personTxt.text="";
  16:             }
  17:              ]]>
  18:     </mx:Script>
  19:
  20:     <mx:TextInput x="10" y="10" id="personTxt" text="" width="145"/>
  21:     <mx:Button x="163" y="10" label="Add" id="btnAdd" click="clickHandler()"/>
  22:     <mx:List x="10" y="40" width="218" dataProvider="{model.items}"></mx:List>
  23: </mx:WindowedApplication>

This 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

Further reading

I recommend you to read the books ActionScript 3.0 Design Patterns and Advanced ActionScript 3 with Design Patterns

Comments

12 Responses to “Simple MVC for Flex and AIR”

  1. Andrew Westberg on February 24th, 2009 2:53 pm

    I’m not sure why you’re re-inventing the wheel here. There are a number of great MVC frameworks for Flex/AIR available: Cairngorm, UM Cairngorm, Mate, Pure-MVC, and Swiz are a few of them.

  2. bserban on February 24th, 2009 6:43 pm

    Hi Andrew,

    It wasn’t my intention to reinvent the wheel, I’ve just wanted to do a simple app in a clean way.
    For sure, as i listed at the end of my article, if you build a large application you should pick a MVC framework for that.
    I think that for a beginner, learning PureMVC in a short time can do more harm than good.

    bserban

  3. Darren on February 24th, 2009 7:35 pm

    I can’t comment on PureMVC but I think you could pick Cairngorm up in a day, the main reason being the heavy use of singletons (which of course many people argue is it’s biggest weakness). Once you work out the flow, it’s dead simple. You do have to create a few files for each task though – a Cairngorm Event, Command and Delegate – but once you’ve registered your event in the FrontController, you can fire off any event in any component of your app and know that it will do what you want it to.

  4. admin on February 25th, 2009 1:14 am

    Never tried Cairngorm, but you both convinced me too take a closer look.

  5. Carsten Schlipf on February 25th, 2009 2:06 am

    We are also using Cairngorm. Another weakness is that the framework does not enforce a clean coding style. With Cairngorm large applications still can become a mess.

    So in case you look at cairngorm, also take a look at the presentation model patterns.

    A lot of people are also very happy with Mate, so you should check this out as well.

  6. Hai Nguyen on March 14th, 2009 6:10 am

    It is depended on the scope of project to make decision of choosing some framework or not. Such simple app like this does not need to use Cairngorm or PureMVC in cases it requires you create a lot of files.

    I am using Cairngorm for a big project and we are pleased with it. It rather simple to use to make loose coupling between UI and Command, but it has many disadvantages: singleton, model locator and it is not rather well for enterprise application if we did not customize it. I think beside MVC model, to have a good design who application (Java, Flex, etc) we should learn other pattern such as mediator, proxy, builder etc and we use existing framework like a skeleton one.

  7. srilakshmi on August 21st, 2009 5:38 am

    Hi,
    Is it possible to have a sort function in proxy??please let me know.Thanks

  8. Rex on November 11th, 2009 2:33 am

    Thanks for the simple approach in explaining MVC for FLEX, was quite easy to understand , this link also helped me

    http://cookbooks.adobe.com/post_Simple_MVC_for_Flex_and_AIR-16199.html

  9. Rex on November 11th, 2009 2:43 am

    Thanks for the simple approach in explaining MVC for FLEX, was quite easy to understand , this link also helped me

    http://askmeflash.com/qdetail/309/how-to-understand-and-use-mvc-framework-in-flex-any-example

  10. Flex and architecture | Miscellaneous musings in beta on January 14th, 2010 5:05 am

    […] dabbling in small projects, the work and investment needed is simply too big. I just found a good post, that goes right to the heart of the Model – View – Controller design pattern. It […]

  11. Madhu on January 20th, 2010 3:22 pm

    Hi,

    Thanks , for posting the example.I request you
    to post the same example by connecting to a remote object. i think that will many of us and get an idea who it looks in real environment.

    Thanks & Regards
    Madhu

  12. madhu on September 28th, 2010 11:18 am

    Hi,

    Can,you please let me known how i can integrate the same exmple with services.I mean the same example connecting backend services such as java , .net , php etc.

    if you can repley me that will help me a lot.

    Thanks,
    Madhu