Getting Started

This tutorial explains how to get started with Mate. As an example, we'll create a stock quote retrieval screen which sends the quote symbol to the server, receives the current price and stores it in the model for the view to show.

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.

Get the source for this tutorial

Creating a new project

In Flex Builder, create a new Flex project called "StockQuotesExample". 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.

The Quote custom event

Every Mate project is driven by events. In the stock quote example, when the user enters the stock symbol and clicks on the "Get Quote" 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 symbol and retrieve the current price.

Our event will be very simple and it will contain one property: the symbol.

package com.asfusion.mate.stockQuoteExample.events
{
   import flash.events.Event;

   public class QuoteEvent extends Event
   {
      public static const GET: String = "getQuoteEvent";
      
      public var symbol : String;

      
      public function QuoteEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
      {
         super(type, bubbles, cancelable);
      }
      
   }
}

The code above assumes this event is contained within the package: com.asfusion.mate.stockQuoteExample.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 a text input and a button:

Dispatching the QuoteEvent

When the user clicks the Get Quote button, we'll create the QuoteEvent and dispatch it:

import com.asfusion.mate.stockQuoteExample.events.QuoteEvent;
   
private function getQuote() : void {

   var quoteEvent:QuoteEvent = new QuoteEvent(QuoteEvent.GET);
   quoteEvent.symbol = symbolInput.text;

   dispatchEvent(quoteEvent );
}

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>

Setting up debugging

In order to know whether our event map is receiving the events that get dispatched, we add the debugger tag to the event map:

<Debugger level="{Debugger.ALL}" />

The EventMap so far:

<?xml version="1.0" encoding="utf-8"?>
<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/">

   <Debugger level="{Debugger.ALL}" />

</EventMap>

Listening for QuoteEvent.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="{QuoteEvent.GET}" debug="true">

</EventHandlers>

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

<mx:Script>
   <![CDATA[
      import com.asfusion.mate.stockQuoteExample.events.QuoteEvent;
   ]]>
</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 stockQuoteExample and it is called QuoteService, you will specify the call as follows:

<RemoteObjectInvoker destination="ColdFusion" source="stockQuoteExample.QuoteService"
   method="getQuote"
   arguments="{event.symbol}"
   debug="true">


</RemoteObjectInvoker>

We are calling the method getQuote 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 "storeQuote" on the QuoteManager class.

<EventHandlers type="{QuoteEvent.GET}" debug="true">
   <RemoteObjectInvoker destination="ColdFusion"
      source="stockQuoteExample.QuoteService"
      method="getQuote"
      arguments="{event.symbol}"
      debug="true">

      
      <resultHandlers>
         
         <MethodInvoker generator="{QuoteManager}"
            method="storeQuote" 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 QuoteManager (if it doesn't already exist) and then call the method storeQuote. 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 QuoteManager

The QuoteManager will handle the business logic that has to do with quotes. It will also store the current symbol's quote so that it can be used by views. In the previous section, we were calling the method storeQuote(price) that stores the value of the current symbol's price. The class definition for this manager is:

package com.asfusion.mate.stockQuoteExample.business
{
   public class QuoteManager
   {

      [Bindable]
      public var currentPrice:Number;

      public function storeQuote(price:Number):void {
         currentPrice = price;
      }

   }
}

Ideally, the currentPrice 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 storeQuote 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 price and that price is stored in the QuoteManager. 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 price:Number;

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

<mx:Label text="Price: {price}" />

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 price stored in the QuoteManager?

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="{QuotePanel}">

   <PropertyInjector targetKey="price" source="{QuoteManager}" sourceKey="currentPrice" />

</Injectors>

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

Event-Service call-Model Manager-View

View-model communication

View the example running, view the source and download the example in the example page.

36 responses

  1. Wow!!! If there was a better word to describe this framework I'd use it. I can't wait to try it out this week.
  2. Very interesting framework. Seems quite lightweight.
  3. I think this framework is easiest to understand. I love them. Good job!
  4. Has anyone thought about integrating the command pattern with Mate for event handling like Cairngorm does? In more complicated applications where you want undo and redo capability its nice to have the command pattern integrated into your event handling. Just a thought.
  5. Tyler,
    The Command pattern is very simple to implement by using the MethodInvoker tag making it call execute. We have a tag that actually does that: CommandInvoker
    What neither the tag nor Cairngorm does is to implement the unexecute function necessary to "undo". That can be done with the MethodInvoker tag too.
  6. Awesome work guys. I like it.
    Thanks for good job!!!!
  7. This framework is very Good,
    Hope you give more demo and information!
  8. First of all, Congratulations for creating such a nice framework!
    I'll try out this framework this weekend and post comments if any in detail later.
    BTW... Do you guys have any statistics on performance overhead of this framework??
  9. Usually I hated a framework for flex. but Mate is different.
    Really It's Great job!
    Plz Don't stop to develop this framework!
    I wish work with this framework for long time :)
  10. All,
    Thank you for your comments!

    Chakree,
    No, we don't have any statistics or benchmarks.
  11. Guyz Great Job ,

    honestly u gave me way to play with frameworks for flex its very light and awsome ..
  12. Mate framework looks really exciting and promising but I think the error reporting needs to be more verbose. For example, How do you use faultHandlers ?

    Just to test, I have added this to the MainEventMap.mxml
    <faultHandlers>
    <MethodInvoker generator="{QuoteManager}"
    method="onFailure" arguments="ERROR" />
    </faultHandlers>

    and I've messed up the wsdl address to an non-existing hostname. So I was expecting the faultHandler fired up and then complain about not being able to find "onFailure" method in QuoteManager. But it didn't happen. It is easy to make typos while dealing with Tags, if they're not caught in compile time, they should be caught in runtime.

    Maybe I did miss something but the reason for me going this practice, I have started to convert an existing cairngorm application of mine to mate and when I have some challenges I wanted to go back and play with the sample application which is way simpler than the application I am working on.
  13. Hi, is it possible to use this framework without MXML documents, eg. in straight up Actionscript without Flex?

    If not, are there any MVC frameworks around that do not require Flex MXML for the UI. I'm coding in Flash CS3

    Thanks,

    PJ
  14. Hi, when I try to run this example in FlexBuilder 3, I get the following errors. Any ideas?

    [RPC Fault faultString="[MessagingError message='Destination 'ColdFusion' either does not exist or the destination has no channels defined (and the application does not define any default channels.)']" faultCode="InvokeFailed" faultDetail="Couldn't establish a connection to 'ColdFusion'"]
       at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::invoke()[E:\dev\3.1.0\frameworks\projects\rpc\src\mx\rpc\AbstractInvoker.as:259]
       at mx.rpc.remoting.mxml::Operation/http://www.adobe.com/2006/flex/mx/internal::invoke()[E:\dev\3.1.0\frameworks\projects\rpc\src\mx\rpc\remoting\mxml\Operation.as:197]
       at mx.rpc.remoting::Operation/send()[E:\dev\3.1.0\frameworks\projects\rpc\src\mx\rpc\remoting\Operation.as:113]
       at Function/http://adobe.com/AS3/2006/builtin::apply()
       at mx.rpc.remoting.mxml::Operation/send()[E:\dev\3.1.0\frameworks\projects\rpc\src\mx\rpc\remoting\mxml\Operation.as:170]
       at com.asfusion.mate.actions.builders::RemoteObjectInvoker/run()[/Users/nahuel/Documents/Flex Builder 3/MateGoogle/src/com/asfusion/mate/actions/builders/RemoteObjectInvoker.as:226]
       at com.asfusion.mate.actions::AbstractAction/trigger()[/Users/nahuel/Documents/Flex Builder 3/MateGoogle/src/com/asfusion/mate/actions/AbstractAction.as:61]
       at com.asfusion.mate.actionLists::AbstractHandlers/runSequence()[/Users/nahuel/Documents/Flex Builder 3/MateGoogle/src/com/asfusion/mate/actionLists/AbstractHandlers.as:325]
       at com.asfusion.mate.actionLists::EventHandlers/fireEvent()[/Users/nahuel/Documents/Flex Builder 3/MateGoogle/src/com/asfusion/mate/actionLists/EventHandlers.as:257]
       at flash.events::EventDispatcher/dispatchEventFunction()
       at flash.events::EventDispatcher/dispatchEvent()
       at mx.core::UIComponent/dispatchEvent()[E:\dev\3.1.0\frameworks\projects\framework\src\mx\core\UIComponent.as:9156]
       at com.asfusion.mate.stockQuoteExample.views::QuotePanel/getQuote()[/Users/peder/Documents/Flex Builder 3/StockQuoteExample/src/com/asfusion/mate/stockQuoteExample/views/QuotePanel.mxml:17]
       at com.asfusion.mate.stockQuoteExample.views::QuotePanel/___QuotePanel_Button1_click()[/Users/peder/Documents/Flex Builder 3/StockQuoteExample/src/com/asfusion/mate/stockQuoteExample/views/QuotePanel.mxml:26]
  15. Peder,
    Regarding your first question, no, not at this time.
    Please ask your more specific questions in the forums.
  16. Wow! I'm extreamly impressed with your framework. This team also clearly understands that a framework is really only as good as it's documentation. The samples, tag references, site layout, organization, and general additude displayed on this site are impeccable.

    I have a growing Flex application, and have opted to stay away from other frameworks because they are all either overkill or appear as though they were slapped together over a couple weekends with lots of cold beer. I have a good feeling about Mate, and will most definately give this a go.

    Great work!

    Tom
  17. I tried importing the source code into my IDE (Eclipse with Flex Builder plugin) and I get the following error which says that CF_FLEX_SERVER_ROOT is not configured. I have installed jboss server installed on my box, do I need to set the CF_FLEX_SERVER_ROOT to the root folder of the default server?

    I am newbie to flex, kindly bear with my ignorance :)
  18. Could someone please tell me why this only fails once and not twice as it should? Doesn't Mate add itself as listener on classes generated on the fly?

    Application:
    <mx:WindowedApplication
       creationComplete="init()"
       xmlns:mx="http://www.adobe.com/2006/mxml";
       xmlns="*">
       
       <TheEventMap/>
       
       <mx:Script>
          <![CDATA[
             private function init() : void
             {
                dispatchEvent(new Event("customEvent"));
                new JustAClass().doDispatch();
             }
          ]]>
       </mx:Script>
    </mx:WindowedApplication>

    TheEventMap:
    <EventMap xmlns="http://mate.asfusion.com/">;
       
       <Debugger level="{Debugger.ALL}" />
       
       <EventHandlers type="customEvent" debug="true" >
          <MethodInvoker generator="mx.controls.Alert" method="methodThatDoesNotExist" arguments="6"/>
       </EventHandlers>
       
    </EventMap>

    JustAClass:
    public class JustAClass extends EventDispatcher
    {
       public function doDispatch() : void
       {
          dispatchEvent(new Event("customEvent"));
       }
    }
  19. Ole,
    The code you show does not work because you are dispatching the event from an object that is not in the display list.

    By the way, it would be better if you ask this type of questions in the forums :)
  20. @Alex Eric

    This is my fault handler setup:
    <code>
             <faultHandlers>
                <MethodInvoker generator="{QuoteManager}" method="faultHandler" arguments="{fault}"/>
             </faultHandlers>
    </code>

    and in QuoteManager

    <code>
          /**
           * Handle the failed remoting call
           */
          public function faultHandler(event:Fault):void
          {
             Alert.show(event.faultString, "Error Executing Call");
          }
    </code>

    The trick here is to make use of the auto-completion within Flex/Eclipse IDE and some debugging to figure out whats going on behind the scenes.
  21. First off - I'm impressed with Mate, I really am. Coming from a Cairngorm perspective, I think this framework is a fantastic tool.

    I just have some comments on the documentation.

    I think most of the docs here are good. But I feel there are things lacking.

    Chiefly, what's lacking is a run down of the various MXML tags that can be used and how to use them - things such as ResponseAnnouncer, that are only talked about in the API. I would like to read an article that explains when you should use each tag, and a small example of it. That way I would feel confident that I could and would use Mate the way it was intended.

    thanks,
    justin
  22. Ok - now i'm a fool.

    Saw the link to Tags. Funny how I missed that before.
  23. Hi,
    Hello from Poland!
    Very nice framework.
    I made CRUD application in this framwerk on 8 ours. I have a few problems but yours documentation is very useful. I am JAVA/PHP programmer and use this languages to handle services in my first flex-made apllication. When I finish i paste sorce code for analyze and discssiion on this forum.

    Mariusz
  24. I think that you mean "note that we use no _prefix_...", not "namespace."
  25. Excellent articulation of the article. Helps anybody who reads it in the first shot.

    Thanks
  26. Excellent framework!! It works like a charm.
  27. Thanks for your great work.
    I want to ask a question. I do not understand why do we need a ModelManager and so a an injector. We can directly set the attribute on view, by a callback so get rid of extra work of defining injector, methods, variables in model manager etc. Ok we want to seperate model and view but generally this is only setting a variable. I really get tired because of this model manager, so started use only callback. What is my drawback? Thanks
  28. Thanks, for the Mate, its incredible.
  29. Hi,
    Can anybody give a example source code of integrating MATE with JAVA.

    Thanks,
    Vasankar
  30. very lightweight and easy to understand i started rocomenting it to my friends too
  31. I cann't wait and shall definitely try this framework.. thanks for this great framework
  32. Wow, really great framework, it's more easier than cairngorm, will be using this in our next project.

    Thanks,
  33. Simply superb, was able to make a sample application up and running using mate with in an hour. Documentation is clear and simple. Thanks Laura !!!!!!!! Mate Rocks!!!
  34. Great work!!!


    Very easily implementable framework.

    Nice and Simple documentation!!!

    Much appreciated.
  35. What is the best practice to pass data back to the view from the event map( using injector or passing data back as a parameter to the CallBack function)?
  36. not helpful , not completed example . it is hard to understand for beginner like me !

Comments now closed