Razvan Surdu Personal Blog

29Nov/090

One simple arhitecture for flex

Project Structure

Project Structure

I am writing this article because many have asked me how to start a flex application and what are some best practices when laying out the foundation. I will create a mini project for this purpose and I will underline some important principals that you should consider when starting a flex application.

Ground rule: Separate your code using the Model - View - Controller design pattern. You don't what to be faced with the situation when you have a lot of lines in a single mxml file and you must quickly fix a critical bug, or you look on someone else code and don't have a clue where to develop the new feature that the project manager wanted.

Starting with the Model, I create a action script class MovieLibModel. In this class I create all the business elements of the application. In my example here I create the public var movies which holds all the movies loaded from the database. The class is a singleton and I can access it's methods from anywhere in the application using the getInstance static method. If I had a more complex application here I would store the user state, his favorite movies or any kind of data that I will later need in the interface.

package model
{
	import mx.collections.ArrayCollection;

	[Bindable]
	public class MovieLibModel
	{
		static private var _instance:MovieLibModel = null;

		public function MovieLibModel()
		{
		}

		static public function getInstance():MovieLibModel
		{
			if (MovieLibModel._instance == null)
			{
				MovieLibModel._instance = new MovieLibModel();
			}

			return MovieLibModel._instance;
		}

		public var movies:ArrayCollection = null;
	}
}

The View is represented by the application interface. Panels, buttons, alert messages and other UI elements form the visual part of the program. This part is mostly created by designers in tools like Photoshop, Fireworks and the exported with Flash Catalist. In flex you create components for the login zone, for product display page etc and you bind the visual elements to the model data. In my example I create two panels one with a datagrid used to list the movies and one with a form for adding a new movie to the databse.

interface

Application Interface




	
		

	

	
		
			
				
					
					
					
				
			
		

		
			
				
					
				
				
					
				
				
					
					
				
				
					
				
			
		
	

Now we must bind the two elements together. When the user inserts a new movie it should be added to the database, and the movie datagrid updated. For this we use the Controller. It's main roles are to handle the actions dispatched by the view, update the model, exchange data with the database or other external services. In this example I use a simple http service to communicate with the backend which is a php script.

package controller
{
	import model.MovieLibModel;

	import mx.controls.Alert;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.HTTPService;

	public class MovieLibController
	{
		static private var _instance:MovieLibController = null;

		public function MovieLibController()
		{
			init();
		}

		static public function getInstance():MovieLibController
		{
			if (MovieLibController._instance == null)
			{
				MovieLibController._instance = new MovieLibController();
			}

			return MovieLibController._instance;
		}

		public var appModel:MovieLibModel = MovieLibModel.getInstance();

		private var myService:HTTPService = null;

		public function init():void
		{
			myService = new HTTPService;
			myService.method = "POST";
			myService.url = "http://localhost/razvansurdu.com/movieLib/server/";
			myService.resultFormat = "array";

			myService.addEventListener(FaultEvent.FAULT, myService_faultHandler);
			myService.addEventListener(ResultEvent.RESULT, myService_resultHandler);
		}

		public function addMovie(title:String, rating:String, description:String):void
		{
			var o:Object = new Object();
			o.title = title;
			o.rating = rating;
			o.description = description;

			o.action = "addMovie";
			myService.send(o);
		}

		public function getMovies():void
		{
			var o:Object = new Object();
			o.action = "getMovies";

			myService.send(o);
		}

		protected function myService_resultHandler(event:ResultEvent):void
		{
			appModel.movies = event.result[0].data.movie;
		}

		protected function myService_faultHandler(event:FaultEvent):void
		{
			Alert.show(event.fault.faultString);
		}
	}
}

Based on this architecture you can add more features, add more visual elements and have a well organized app, easy to debug and maintain.

7Nov/090

Convert a Xml to an ArrayCollection in AS3

Here is a quick method to convert a xml to an array collection. Because you pass the XML url (Eg: './assets/data.xml') to the first argument you will receive the array asynchronous using the callback function. If you have already the xml content in a variable use only the code in the anonymous function at the event.COMPLETE dispatch.

static public function convertXmlToArrayCollection( xmlUrl:String, rootTag:String, repeatedElement:String, callback:Function ):void
{
	var xmlLoader:URLLoader = new URLLoader();
	xmlLoader.addEventListener(Event.COMPLETE, function(e:Event):void
	{
		var xml:XMLDocument = new XMLDocument( e.target.data );
		xml.ignoreWhite = true;

		var decoder:SimpleXMLDecoder = new SimpleXMLDecoder();
		var data:Object = decoder.decodeXML( xml );
		var array:Array= ArrayUtil.toArray(data[rootTag][repeatedElement]);

		callback(new ArrayCollection( array ));
	});
		xmlLoader.load(new URLRequest(xmlUrl));
}