Avg. Rating 3.7

Problem

In this simple article we’ll explore how simple it is to implement History Manager functionality in a MVC Flex application and the basic rules of mvc pattern architecture.

Solution

We will use an mvc design pattern to keep the graphic views separated from the data that will store the current state of ours application.

Detailed explanation

How to implement History Manager in a MVC Flex Application

[Gallo_Teo] - Matteo Lanzi

In this simple article we'll explore how simple it is to implement History Manager functionality in a MVC Flex application and the basic rules of mvc architecture. 

I'll use Adobe Cairngorm as micro architecture  but  the concept is the same if you want to implement it with pureMVC.

A working example can be found here.

Application Overview

The test application is very simple; it's a normal image gallery that takes images from the server and displays them in "Tile View" or in "Detail View".
The target of this tutorial is to catch a good application strategy to implement easily the History manager, so that the user will be able to go back and forward in his navigation through the buttons of his browser

Therefore, the steps to create this simple application are:

1. Create a Business Class that has to request the server ( ImageDelegate.as )

2. Create a command, so that the application can query the server ( GetImageCommand.as )

3. Create a Model where the command will store the images gotten from the server ( Model.as )

4. Create the view interface to display the result

5. Implement the History Manager Strategy.

To reflect the typical cairngorm mvc architecture I've created this project structure.

That's very simple but very clean, you can reuse it for a lot of projects.

1  - Business and delegates

Under the business package we will find all the classes that communicate with the server, with audio stream, video stream, file stream, xml and so on. All the requests that are Asynchronies are part of the business package.

If this is the first time you've been hearing about "mvc" please refer to Steven Webster articles on Adobe web site for more detailed information about mvc and cairngorm.
http://www.adobe.com/devnet/flex/articles/cairngorm_pt1.html

However  don't worry, these concepts are very simple and will be more clear in the next section

Oue ProducDelegate class has to request the server the list of images, and can implement also a lot of functionality such as resize image request, a specific image url and so on.
It has to communicate with the server side services.

In our case we really don't need to do that so we can implement it as a fake service in this way

 public class  ImageDelegate{ 
                protected var responder : IResponder ;   
                 public function ImageDelegate( responder :
IResponder) {   
                     this.responder   = responder ;    
          }   

          /**   
           *    
           * @ getImages   
           * get all Images from the server    
           * now it is a fake for the tutorial   
           * */   
             public function getImages ( ) : void {                
      
                   
//-- create a fake image list   
                     var list : Array =  new Array () ;   
                     for (var i : int = 0; i< 14 ; i++ ){       
                 
                             var image : ImageVo = new ImageVo () ;
  
                          image.id = "id"   + i ;    
                          image.imagePreview =  "./data/" +
i.toString() + ".jpg" ;   
                          list.push( image ) ;    
                  }                                   
                  responder.result( list ) ;                    
          }   

          /**   
           *    
           * example   
           * */   
             public function getImagePreview () : void {           
           
          }   

           
//   ......  
          /**   
           *    
           * delegate store all the functions about a remote   
           * service... this is the exampel : )    
           *    
           * so the commanda can reuse this in different way    
           * depending from the context    
           * */   
             public function resizeImage(): void {  }
  }

2 - Commands

The MVC architecture is very intuitive; the concept is: " Does our application need something?" OK ! it has to give a "Command".

Think about it, does the user click a button to view a product ? Will our button dispatch something like "ViewProductCommand", or does the user want to search something ? The application will dispatch something like "getSearchedProductCommand". Our case is easier and we only need to get a list of images so we will have a command "GetImagesCommand".

In order to do that we will implements a Cairngorm class that's " ICommand" which simply has one method called execute.

  public class GetImagesCommand implements ICommand, IResponder {  

             protected var model : Model ;     

             public function execute(event:CairngormEvent): void { 
 
                  model = Model.instance ;    
                     new ImageDelegate(this).getImages() ;      
          } 
  … 

In the "execute" method we call "getImages" function of ImageDelegate class (?)
I think now you can imagine the importance of the delegate: we can have a single delegate for all the services and a lot of different commands for a specific use.

As I said before the request to the server is asynchronous, so a delegate has to know which command to ask for a service and give it back to the answerer.
It's for this reason that in the command class we implement IResponder interface too; this will allow the answerer to delegate to the correct command.
In case we don't use delegate, our command could die after the execute function because no object refers to it.

Here is the command

new ImageDelegate(this)   

and in delegate class when it receives the answerer it does

responder.result(list) ;   

this is the complete GetImagesCommandCode; you can see that , by implementing IResponder interface, we have two method ( fault and result ) that are the delegate answerer

  public class GetImagesCommand implements ICommand, IResponder    
{   
             protected var model : Model ;     

             public function execute(event:CairngormEvent):   void 
    {   
                  model = Model.instance ;    
                     new ImageDelegate(this).getImages() ;    
          }                 

            /**   
           *    
           * @result   
           * occurs when the delegate succefully    
           * query the server    
           * */   
             public function result(data:Object): void {   
                     var list : Array = data as Array ;   
           
                     if ( ! list ){   
                          fault("no array") ;   
                           return;       
                  }             
                  model.images = new ArrayCollection ( list ) ;    
                     if ( list.length > 0 )    
                          model.currentItem =
model.images.getItemAt( 0 ) as    
Report abuse

Related recipes