In this series we are going to be creating a fully functional RIA, under the stick standards of the Cairngorm Framework. Instead of demonstrating this application with non-dynamic data (which I have when people do). We are going to be using a live MySQL database on a live server where our amfphp installation lives.
This might be a long and bumpy ride, but in the end I promise that you will have a greater understanding of the Cairngorm Framework. This will teach you what actually goes into building a Rich Internet Application from the ground up, while following the architecture standards that the Cairngorm provides.
I am going to try my best to keep this as real as possible, with no static data. I definitely will not leave any source code out. Also on that note, there will not be any sayings like "Ok, now that you have seen how to make a RemoteObject call, you can just switch the methods, add a few args, and wham there you have it." I WILL explain what goes into every call, and every function and every response.
Alight, with that out of the way, lets create a hit!
Requirements
The following is required to complete this tutorial.
Architecture
For this simple application we are going to be using the Cairngorm Framework, I know it is over kill but this is great practice on how to build application with Cairngorm and how it works.
Cairngorm Overview
Model View Controller based architecture
Cairngorm is based on the MVC model. It is specifically designed to facilitate complex state and data synchronization between the client and the server, while keeping the programming of the View layer detached from the data implementation.
The role of the View layer in a Cairngorm application is to throw events and bind to data stored in the Model. Components on the View can bind to Value Objects or other properties in the Model (data) layer.
In a Cairngorm Model, related data are stored in Value Objects (VOs), while simple variables can be stored as direct properties of the ModelLocator class. A static reference to the ModelLocator singleton instance is used by the View layers to locate the required data.
The Controller is the most sophisticated part of the Cairngorm architecture. The Controller layer is implemented as a singleton FrontController. The FrontController instance, which receives every View-generated event, dispatches the events to the assigned Command class based on the event’s declared type.
The Command class then processes the event by running the Command class’ execute() method, which is an ICommand interface method. The event object may include additional data if required by the developer. The execute() method can update the central Model, as well as invoke a Service class which typically involves communication with a remote server. The IResponder interface, which is also implemented by the Command class, includes onResult and onFault methods to handle responses returned from the invoked remote service.
-Source wikipedia.org
Brainstorm
All great applications start with a blue print, or a thumbnail sketch of how the application should act, respond, and the workflow process. So lets go ahead and go outside or someplace quite with a pen and a piece of paper, and mock up how this application is going to operate.
Extra credit: Sketch out this app from the information and visuals stated earlier, feel free to send me what you did, I want to see!
Here is my sketch:
Click for full size:
Overview ( Textual / Visual )
Textual
Here is how this application is going to work. The 3 components are going to represent the different views/states in our application. The LinkView (which is the main view) is going to present a list of links from the database to the user, this view also will be used for creating a new link, and displaying the details of that link. When a link is selected in the LinkList component, the information about that link are going to be displayed in the LinkDetail component, from there the user can either hide the details, and browse through the different links, or view the selected link in a new window of there web browser. Back to the LinkList component, when the (add link) button is clicked, the LinkForm component will be displayed, this is where you can create a new link for display. After the link is validated and created, the LinkForm component then disappears and the LinkList component refreshes the links.
Visual
Click the image for full size.
Finished View
Here is what our application is going to look like when it is finished.
Value Object and Model Locator Pattern
Value Object
When developing applications in Flex you should create classes or objects that represent an value. For example, in Whats Ur Link, the one thing that we must represent is the link! Each link has a number of link attributes, such as id, title, url, category, description, and date.
Useful structures can be exchanged or transferred between tiers in your application. On the server side, this is how we are going to populate our queries with, data stuffed in a VO and sent over the wire. Then we will then take the VO and content it into a collection of custom value objects (VOs) to return to the client. Flex can then de-serialize each VO in the collection into the corresponding VO on the client.
VOs are used to create a layer of business objects that can be transferred between tiers, instead of using results sets, and data-sets.
Here is our LinkVO:
LinkVO.as:
1: package com.jonniespratley.on_flex.tutorial_tuesday.whatsurlink.model.vo
2: {
3: import com.adobe.cairngorm.vo.ValueObject;
4: import flash.net.registerClassAlias;
5:
6: //For AMFPHP
7: [RemoteClass(alias="vo.com.jonniespratley.on_flex.tutorial_tuesday.whatsurlink.LinkVO")]
8: [Bindable]
9: public class LinkVO implements ValueObject
10: {
11: public var link_id:String;
12: public var link_date:String;
13: public var link_category:String;
14: public var link_url:String;
15: public var link_name:String;
16: public var link_sort:String;
17: public var link_description:String;
18:
19: public function LinkVO( source:Object = null )
20: {
21: if ( source != null )
22: {
23: for ( var element:String in source )
24: {
25: try {
26: this[element] = source[element];
27: }
28: catch ( error:Error )
29: {
30: throw new Error ( "LinkVO" + error );
31: }
32: }
33: }
34: }
35: }
36: }
Explanation of code:
This class represents our data that we are expecting to receive from our server. This contains all of the fields in our database table; id, title, url, category, description, and date.
In the constructor we have a helper method, but we will explain all of that a little later.
The Model Locator
The Model Locator pattern is a singleton and was created purely to be used with Flex application development. In this case, a singleton is a design pattern that allows for only one instance of the Model Locator to be present within your application’s memory. Any data that you think is required to live in the application’s state should be stored inside the Model Locator. The Model Locator creates a central area where all the states can be held in your Flex application. This allows the view components to bind to the model or state of the application and keep everything up to date.
Summary:
- Global Singleton repository for global data
- Does not contain business logic
- Serves as caching and access location only
- Class Implements IModelLocator
- Must have a getInstance() method
- Holds public variables for global data access
Here is our Model Locator for Whats Ur Link?
ModelLocator.as
1: package com.jonniespratley.on_flex.tutorial_tuesday.whatsurlink.model
2: {
3: import com.adobe.cairngorm.model.IModelLocator;
4:
5: [Bindable]
6: public class ModelLocator implements IModelLocator
7: {
8: //Instantiate the ModelLocator
9: private static var _instance:ModelLocator;
10:
11: //Get the instance of the ModelLocator
12: public static function getInstance():ModelLocator
13: {
14: if( _instance==null ) _instance = new ModelLocator();
15: return _instance;
16: }
17:
18: public function ModelLocator()
19: {
20: if( _instance != null )
21: throw new Error( "Error: Singletons can only be instantiated via getInstance() method!" );
22: ModelLocator._instance = this;
23: }
24:
25: // ******************** Public Link Variables *********************** \
26:
27: // ******************** Work View States **************************** \
28: }
29: }
Explanation of code:
1: import com.adobe.cairngorm.model.IModelLocator;
2:
3: [Bindable]
4: public class ModelLocator implements IModelLocator
5: {
6: //Instantiate the ModelLocator
7: private static var _instance:ModelLocator;
It is very very import to make this entire class Bindable by adding a [Bindable] meta tag at the top of the class, we are making this class bindable so we can use the data binding feature in Flex to bind from one data source. Then we create one variable called "_instance" and this is of type ModelLocator, our ModelLocator. This will store an instance of our own class within its class, make sure that this variable is a private static variable.
1: //Get the instance of the ModelLocator
2: public static function getInstance():ModelLocator
3: {
4: if( _instance==null ) _instance = new ModelLocator();
5: return _instance;
6: }
The getInstance function is how we access our MOdelLocator from all parts of our application. This is a really simple function, all that it does is passes back our "_instance" variable, which is our class, and returns it. If no instance of our class is created, it creates one anyways.
To access our ModelLocator class from anywhere in our application, we just simply use this:
private var model:ModelLocator = ModelLocator.getInstance();
That wraps up this week’s tutorial of this 5 part series, come back for next week when we start to build the views, and more of our core components to make this app run.