This is the second in my series on my adventures learning about the robotlegs framework. In my first post I spoke about Article 2 focuses on the model, and that is what I will talk about in this article.

What is a Model?

If you've been around in the development world for a while, you've probably heard the term model. It is even part of the name of one of the most pervasive design patterns, Model View Controller, or MVC for short. A model usually contains data storage, often in a database level, and classes to load, and store, that data into memory. Your data is often stored in memory as 'dumb' objects, called Value Objects in the Cairngorm world and Data Transfer Objects in many other situations.

Often a Model is more than just a collection of dumb data containers, though. It will include objects that contain business logic and other application specific knowledge. One example may be a Shopping Cart object which probably contains a lot of data which is not analogous to a single database table. It also probably contains business logic such as the total price of all items in the cart.

In Cairngorm, there was a ModelLocator which would contain model objects. It was often a big data storage object. In the Cairngorm projects I worked n, the move was to have a single ModelLocator with all your global data in it. RobotLegs has directed me to a different approach.

Build out Multiple Models

In my RobotLegs development, I have been building multiple, focused, models. For the most part each model class I create is just a way to store data in memory for use in multiple places. In the current application I'm building, I have a model for search criteria, which stores the criteria a user entered into the search form. Based on that data, I may call any one of four different remote procedures to retrieve search results.

I also have a model for user authentication information. There is a model that contains Controlled Vocabulary dataProviders for ComboBoxes and Lists used across multiple forms. I like this approach because I'd rather have a lot of independent focused, objects instead of one big object with lots of unrelated data.

A sample Model may look like this

view plain print about
1package com.flextras.model
2{
3 import com.flextras.vo.UserVO;
4 import org.robotlegs.mvcs.Actor;
5    
6 public class UserModel extends Actor
7 {
8 public function UserModel()
9 {
10 super();
11 }
12        
13 public var user : UserVO;
14 }
15}

The model class is just a class like any other ActionScript class you're used to creating. Model extends the Actor class, which is a helper class included as part of the Robotlegs framework. Actor includes code for implementing the dispatch method. The dispatch method can be viewed as a parallel to Flex's dispatchEvent method. Where dispatchEvent uses the internal Flash Player mechanism to dispatch events to a component's parent, the Robotlegs dispatch method will dispatch events to the model's context. Mediators, as discussed in part one of this series, can listen to context events. This is a unique way to tell the rest of your application that something important happened. I'll expand more on context events in a later entry to this series.

Dependency Inject that Model!

Now that you've created the model class, what can you do with it? You'll want to add it into your mediators using Dependency Injection. Dependency injection is a design pattern that means the system will create objects for you automatically, and set them as instance variables on the objects that need them. To use Dependency injection with Robotlegs I've been following these steps:

  1. In your context, define the type of injection that occurs.
  2. In the mediator, define the variable with the inject metatag.

These are two simple steps, but they can be very powerful. First, in your context, you want to set up your object to be used for injection purposes. The context includes a variable called injector and injector has many methods for injecting the class. To inject the UserModel as a singleton, do this:

view plain print about
1injector.mapSingleton(UserModel);

There are other forms of mapping, but I have stuck to mapSingleton for this project. The value of the map method is a class name. We do not create an instance of the class. The injector deals with that. In your mediator, you use the inject metadata to get your singleton instance into the mediator. Put the metadata before the variable that will represent your UserModel instance:

view plain print about
1[Inject]
2public var user : UserModel;

The rest of the magic occurs automagically. At runtime, the injector knows to create a single instance of UserModel class. It knows to set the user property of our mediators to that single instance.

It is worth noting that Robotlegs uses swiftSuspenders under the hood for dependency injection. I have not spent any time exploring it in depth yet.

Once the model is in the mediator, what do you do with it? It depends on the type of data and how you want to do it. I have used models to pass search criteria into a service and I've used them to pass data into a view for display. I've also updated model data from the mediator.

A Review

So, let's see what is going on in a Robotlegs process:

  1. A component loads, and initializes the context.
  2. The context runs the startup procedure.
  3. The startup procedure prepares classes for dependency injection and maps mediators to views.
  4. After a display component is created, and added to the stage, Robotlegs creates it's mediator.
  5. RobotLegs injects all appropriate objects into the view's mediator
  6. The mediator's onRegister method executes.

How we make use of injection, models, and mediators will depend on what you want to accomplish with your application.

What Next

I'm planning at least three more entries into this series. The next one will cover using Services with Robotlegs. Services are how your Flex application gets data from your backend.