May
13

Cairngorm - 3 Commands

In the previous tutorial we covered CairngormEvents. With their Publish/Subscribe model event dispatchers, we were able to communicate directly with event handlers (more or less). In this tutorial, we are going to build upon how Cairngorm handles events. As in the last tutorial, we will be using the CairngormEventDispatcher to dispatch events. We are still free to use the Cairngorm EventDispatcher to listen to events, but this time we won’t. Cairngorm provides the FrontController to map specific events to specific Command classes. As we did before, we are able to assign multiple handlers to a single event.

To get started using the Cairngorm FrontController, it is necessary to include it in your Application. I almost always include it as one of the first MXML items in my file.

// Tutorial_3.mxml
    
    
<!-- Cairngorm Initialization -->
    <
control:AngryController id="angryController" /> 


Now that we have a controller in our Application, we need to make some event mappings to commands. The FrontController has only one public method, called “addCommand”. This function maps an event to a command, working the way a call to addEventListener works on other classes. But instead of mapping an event to a function, it maps a command to a function. Commands, in this case, can be thought of as event handlers.

// AngryController.as
    
    
public class AngryController extends FrontController 
    {
        
public function AngryController():void    
        {
            super
();
            
            
// Used in Tutorial 3
            
addCommandTutorialEvent.ADD_ITEM,        AddItemCommand );
            
addCommandTutorialEvent.REMOVE_ITEM,    RemoveItemCommand );    
         
}
    } 


Notice that the event types are being brought in from the events themselves. This is a stylistic decision, and you are free to get the event types from wherever you want. Whatever you decide, make sure they are constants. I like having the event types declared in the events that carry the data for those events.

Now that we have our mappings, it’s time to write our event handlers (commands). Commands, in their simplest form, must implement ICommand, and contain an “execute” function.  The first event handler (command) we will be writing is AddItemCommand. As the name implies, it adds an item to a list.

// AddItemCommand.as

    
public class AddItemCommand implements Command
    {
        
public function executeevent CairngormEvent ):void 
        {    
            
var model SampleModel SampleModel.getInstance();
            
            if( 
event.data != null )
            
{
                model
.listData.addItemevent.data );    
            
}
            
        }        
   
    } 


As we discussed in the previous tutorial, CairngormEvent has a data field. AddItemCommand will look in that data field for the object to add to the list. If the data field’s value is not null, it is inserted to the list. That’s all. AddItemCommand isn’t a very complex class, but it is a nice compartmentalized unit of work. The next task at hand is writing RemoveItemCommand:

// RemoveItemCommand.as

    
public class RemoveItemCommand implements Command
    {
        
public function executeevent CairngormEvent ):void 
        {    
            
var target String Stringevent.data );
            
            var 
model SampleModel SampleModel.getInstance();
            
            for 
each( var item Object in model.listData )
            
{
                
if( item.id == target )
                
{
                    model
.listData.removeItemAtmodel.listData.getItemIndexitem ));
                    return;
                
}    
            }
        }
    } 


RemoveItemCommand looks a whole lot like AddItemCommand, in that it isn’t a very complex class. This time, the data field in the CairngormEvent is being used to send the id of the item to be deleted. If the id is found in the list, that item is removed.

One thing I really like about this approach to writing applications: you can sit down at the beginning, and, depending on your feature set, get most if not all your command writing out of the way. Another upside is that you know where to look first if, God forbid, you have bugs in your system.

All that is left for this lesson is to exercise our new commands. This time we are going to be, you guessed it, adding and removing items from a list. To do this, we add the following components below a List. Not that as in our past tutorials, our list is being populated via a model.
 

// AngryPanelT3L2.mxml
    
    
<mx:HBox>
        <
mx:TextInput id="itemName" width="100" />
        <
mx:Button label="Add Item" click="addItem()" enabled="{itemName.text.length > 0}" />
    </
mx:HBox>
    
    <
mx:HBox>
        <
mx:ComboBox 
            id
="removeBox"
            
width="100"
            
dataProvider="{model.listData}" 
            
labelField="title" 
            
rowCount="6" />
            
        <
mx:Button label="Remove Item" click="removeItem()" enabled="{model.listData.length > 0}" />    
    </
mx:HBox


Inside the first Hbox, you will see a TextInput and a Button. Anything you type in the TextInput will become an item in the list.

Below the HBox, you will see a ComboBox and a Button. This ComboBox has its data bound to the model as well. When you choose an item from the list and click the Button, the item will be removed from the list. Both Buttons call functions in the Actionscript, to build the list and dispatch the events:

// AngryPanelT3L2.mxml
     
    
public function addItem() : void
    {
        
var Date = new Date();
            
        var 
event TutorialEvent = new TutorialEventTutorialEvent.ADD_ITEM );
        
event.data {id:d.getUTCMinutes(), title:itemName.text};
        
CairngormEventDispatcher.getInstance().dispatchEventevent );
    
}
    
    
    
public function removeItem() : void
    {
        
var event TutorialEvent = new TutorialEventTutorialEvent.REMOVE_ITEM );
        
event.data removeBox.selectedItem.id;
        
CairngormEventDispatcher.getInstance().dispatchEventevent );
    


These two functions make TutorialEvents of types that match what we put in our mappings at the beginning of this lesson. Based on our mappings in the FrontController, certain event handlers (the ones we wrote earlier) will be called. That’s it!

(Note that the function addItem includes some code that might look like mumbo jumbo, involving “Date.” This bit is used to create a unique id for each event.)


Conclusion

To run down what just happened: we made mappings and tied event types to event handlers (commands). Our commands updated values on the model. Our UI is tied to values in the model, and was automatically updated when the commands did their job.

I highly suggest incorporating commands into your application as they are a great way to encapsulate the functionality of your application. Happy Coding!

Next lesson - Delegates

Comments

There are no comments for this entry yet.

Enter a comment - moderated

Add Comment