<< RIA Bhubaneswar

Blog

Our Blog

Blog Home | About | Entries By Date | Search

Mate -- An Event Based Flex Framework


Entry posted 07/05/10 by Mr. Avijit Maji , tagged: Rich Internet Apps, Development, Design
1,571 views, 0 comments.

Title
Mate -- An Event Based Flex Framework

Entry

Mate (pronounced mah-teh)-- a tag-based, event-driven Flex framework, created by Nahuel Foronda and Laura Arguello of AsFusion. Flex applications are event-driven. Mate framework has been created to make it easy to handle the events your Flex application creates. Mate allows you to define who is handling those events, whether data needs to be retrieved from the server, or other events need to be triggered. Mate provides a mechanism for dependency injection to make it easy for the different parts of your application to get the data and objects they need.

Image

More

 

Like other frameworks, Mate addresses the common architectural concerns in Flex such as event handling, data binding, and asynchronous processing. One way Mate differentiates itself is by utilizing the built-in event-driven nature of Flex applications rather than building a framework-specific event architecture. Another differentiators is that Mate is entirely tag-based. It focuses on easy-to-use and well-documented tags that handle common application tasks such as listening for events, sending remote object calls, and handling results. Much of this is managed within Mate's concept of an EventMap, which routes the application flow, defining, for example, what the responses to particular events will be, how remote object responses are handled, and which values are injected into particular views. If this sounds intimidating, don't worry; it's actually quite straightforward, and it will become clearer as we walk through our sample application.

 

Mate is design to take advantage of MXML and regular old Flash events dispatched the regular way, not through the framework like Cairngorm or Swiz (although Swiz is open to regular event dispatching if you set it up yourself). In that way it’s like PureMVC. But Mate uses the fact that part of the framework is defined right at Application level to make the event-driven part of the framework very unobtrusive and easy.

Since it’s very unobtrusively event based (you’ll see what I mean in a bit) it allows you to make a very componentized application easily, and although of course you can use the classes from the framework in ActionScript form, you’ll be surprised at how much you can do right in MXML.



Getting Started:

All Mate projects must have:

1. One or more events (custom or built-in)

2. One or more Event Maps

Typically, the basic steps to create a Mate project are:

1. Add the compiled framework code to your project (Mate.swc).

2. Create a file that will be the EventMap .

3. Include the event map in your main Application file.

4. Create a custom event.

5. Somewhere, dispatch that event.

6. Add EventHandlers in your event map that listen for the event type you dispatched.

7. Execute some actions inside the EventHandlers block (ie: call the server, store data, etc).

8. Repeat 4-7 for every event you need.

 





 

In Flex Builder, create a new Flex project called "LoginExample". Let the main source folder be "src"

(default folder).

In the libs folder it creates, place the compiled framework SWC (Mate.swc). This will let you use all Mate classes

and tags.

 

Every Mate project is driven by events. In the Login example, when the user enters the user name and password and clicks on the "Submit" button, we'll create a new event containing that information that will be sent to the

server. Therefore, we need to create a custom event to indicate that the user wants to submit the user name, password and retrieve success from server.

Our event will be very simple and it will contain two property: userName, password

package com.mate.loginExample.events

{

import flash.events.Event;

public class LoginEvent extends Event

{

public static const GET: String = "getLoginEvent";

public var userName : String;

public var password : String;

public function LoginEvent(type:String, bubbles:Boolean=true,

cancelable:Boolean=false)

{

super(type, bubbles, cancelable);

}

}

}

 

The code above assumes this event is contained within the package: com.mate.loginExample.events

The event also contains a constant that we will use to specify the event type. One event can specify more than

one event type. We also make this event bubble up by default (the second argument of the constructor). Otherwise, we will need to remember to specify it when we instantiate it.

 

Creating the UI

 

The user interface will only need two text inputs, one for User Name and other for Password entry and a button to submit:

 

Dispatching the LoginEvent

 

When the user clicks the 'Submit' button, we'll create the LoginEvent and dispatch it:

import com.mate.loginExample.events.LoginEvent;

private function getLogin() : void {

var loginEvent: LoginEvent = new LoginEvent(LoginEvent .GET);

loginEvent.userName = username.text;

loginEvent.password = password.text

dispatchEvent(loginEvent);

}

 

 

The Event Map

The EventMap is where we place the handlers for all the events the application creates (there could be more than one event map, though).

To add the event map, we need to create a new MXML file, with name "MainEventMap". This component must extend from EventMap . At this point, the event map would be empty and it should look like this:

<?xml version="1.0" encoding="utf-8"?>

<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/">

</EventMap>

 

Note: we use no namespace for http://mate.asfusion.com so that we don't have to add it to every tag in the

event map. You can copy the code above to your file as a starting point.

We'll add the event map to our main Application file:

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"

xmlns:maps="com.asfusion.mate.stockQuoteExample.maps.*">

<maps:MainEventMap />

</mx:Application>

 

 

 

Listening for LoginEvent.GET

 

In our event map, we will listen for the quote event so that we can send the request to the server.

We'll add an EventHandlers tag that will specify the event type we are listening to. We'll also set the debug attribute to true so that we can see when the handlers run in the debugging output window.

<EventHandlers type="{LoginEvent.GET}" debug="true">

</EventHandlers>

At the top of the event map we'll need to import the event class.

<mx:Script>

<![CDATA[

import com.mate.loginExample.events.LoginEvent;

]]>

</mx:Script>

Inside this EventHandlers block, we'll place the actions we want to perform when the event is dispatched. In this case, we would like to make a server call, for which we'll use the RemoteObjectInvoker tag. Assuming the service in a folder called loginExample and it is called LoginService, you will specify the call as follows:

<RemoteObjectInvoker destination="ColdFusion" source="loginExample.LoginService"

method="getLogin"

arguments="{event.userName},{event.password}"

debug="true">

</RemoteObjectInvoker>

We are calling the method getLogin on that service and sending the symbol coming from the event as an argument of the remote method call.

 

 

Handling the server result

 

The server returns a numerical value with the stock's current price. We will handle that result inside the

RemoteObjectInvoker 's resultHandlers and call the function "loginStatus" on the LoginManager class.

<EventHandlers type="{LoginEvent.GET}" debug="true">

<RemoteObjectInvoker destination="ColdFusion"

source="loginExample.LoginService"

method="getLogin"

arguments="{event.userName},{event.password}"

debug="true">

<resultHandlers>

<MethodInvoker generator="{LoginManager}"

method="loginStatus" arguments="{resultObject}"/>

</resultHandlers>

</RemoteObjectInvoker>

</EventHandlers>

If you have shared data that many views will access, you may want to create a "model". In this simple example, you don't really need a model, but because it is something you will usually need, we'll add it anyway. Inside the resultHandlers, we are using a MethodInvoker to create an instance of LoginManager (if it doesn't already exist) and then call the method loginStatus. Inside the resultHandlers, we can access the result coming from the server, which we can pass as the argument of the method call.

 

Creating our Model, the LoginManager

 

The LoginManager will handle the business logic that has to do with login. It will also store the current login status so that it can be used by views. In the previous section, we were calling the method loginStatus(status) that stores the value of the login status. The class definition for this manager is:

package com.mate.loginExample.business

{

public class LoginManager

{

[Bindable]

public var currentStatus:String;

public function loginStatus(status:String):void {

currentStatus = status;

}

}

}

Ideally, the currentStatus property would be read-only instead of public. But in order to do that and still making it bindable, we will need to do some additional work.

Also, when the method loginStatus is called, we can execute any necessary business logic.

 

 

Showing the current price value in the view

 

So far, when the event is dispatched, we make a service call, the server returns the current login status and that status is stored in the LoginManager. But now we need to be able to show that value in the view.

In the view where we want to show the price, we'll add a property:

 

[Bindable]

public var status:String;

and then show that number anywhere in the view we want, for example, in a Label:

<mx:Label text="Login Status: {status}" />

 

That's all we need in the view.

 

Getting the current price from the model Manager to the view

 

But how does the view get this variable populated from the status stored in the LoginManager?

In our event map, we'll add another set of tags. These tags will assign a property on the model to a property on the view, and because the property on the model is bindable, the view will always get the most current value.

<Injectors target="{LoginPanel}">

<PropertyInjector targetKey="status" source="{LoginManager}" sourceKey="currentStatus"

/>

</Injectors>

When you add this, make sure you have all the necessary import statements at the top of your event map.

 

 

 

 

 

 

 

 

 

Overall Thoughts:

Mate does a great job of accomplishing its purpose, and I especially like that the only place you'll find Mate code is in the EventMap. Otherwise, my code was completely spotless, with each class having its own concerns and not at all worried about how to get information to and from other parts of the program. Some developers have reported that they don't like debugging with Mate, but I think they have done a great job with the Debugger. I found the errors to be easily intelligible so that I could find and fix the problem without much of a fuss.

That being said, there were a number of things that made me pretty uncomfortable using Maté. Possibly some of those issues are just my inexperience with frameworks in general and this one in particular, but I found them worth mentioning.

Keywords
Mate frameworks, Event Based Flex framework