
Truckin' thru MVC
Taking Control
In Part II of this series on the MVC, we saw how we could separate the Model (data provider) from the View (a representation of the Model’s data—a graphic compass.) The process was simple enough, especially since all we needed from the Model was a value between 0 and 360. We made it even simpler by using constants with cardinal directions. In this final piece of the MVC puzzle, we’re adding a Controller class. The Gang of Four state that the
…Controller defines the way the user interface reacts to the user input
The UI for the controller is a Slider component set up with values ranging from 0 to 360. The View class instantiates the Sldier with Slider change events sent to the Controller class. In turn the Controller sends the Slider values to the Model, which updates its current value. The update is sent to the View class which rotates the compass needle.
So as not to lose sight of why we’re going through all this trouble, keep in mind that by decoupling the model, view and controller we can increase the flexibility and reuse of the program. In this post, we’ll see how we can create an analog compass, and in Part IV of this series how we can add different kinds of views that display the same information. To get started, take a look at the revised Analog Compass using a Slider for changing the position of the compass needle. Slide the Slider thumb-press along the top left and right. (Also, try pressing and holding down the left and right arrow keys.)
![]()
As you can see, the compass needle moves as soon as the Slider stops and the thumb-press is released. You could get a livelier motion using a few more lines of code, but for now, we’ll keep it simple and focus on the design. Figure 1 shows what you will see.

Figure 1: Analog Compass controlled by Slider and Arrow Keys
The compass rose and the needle are both instantiated as Sprites in the program but were created in the Library as MovieClip classes. No Timeline commands were required so instead of treating them as MovieClips, both could be used as Sprites. You could do the same thing with externally loaded SWF files placed into dynamically created MovieClip classes.
We Need to Talk
For everything to work, the classes need to talk. A Client class uses the Model, View and Controller classes that in turn communicate with one another. Figure 2 shows the communication pattern the MVC classes. The Client instantiates all three classes and sets an event listener to a Model instance to listen for an update notice and to invoke a View method when an update occurs.

Figure 2: MVC Communication
As you can see in Figure 2, the Model and View keep each informed of states and the Controller sends the Model changes made by the user who is either dragging the Slider control or pressing the left and right arrow keys.
The Client
Like all Client classes, this class makes requests. However, rather than communicating with a single class or multiple classes through an interface, this Client uses all three—Model, View and Controller. One of the most interesting elements I found in fiddling around with the MVC is the way it uses events and event handling. The Client sets up a Model event listener that fires an update method in the View instance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package { import flash.display.Sprite; public class Client extends Sprite { private var model:Model; private var view:View; private var controller:Controller; public function Client() { model = new Model(); controller=new Controller(model); view=new View(model,controller,root); model.addEventListener(Model.UPDATE, view.update); } } } |
Notice that both the View and Controller instances hold a reference to a model instance in their constructors. Further, note the use of the root property. When ActionScript 3.0 came along, I gave up using any reference to root because I associated it with the old ActionScript. However, had I bothered to read about root in the ActionScirpt 3.0 Reference, I would have found that it is a new root. It’s very handy for placing objects where you want them to go.
Model
As you can see and no doubt expected, the Model contains a getter and setter for the value to be used by the rotation value of the compass needle. However, much more interesting, is how the EventDispatcher is employed. In Chandima’s work, he uses both the IEventDispatcher and EventDispatcher, and Bill and Anthony use the EventDispatcher. It allows you to make an event in your object that can be fired when called upon. The notify method may remind you of the Observer Design Pattern, and indeed it should. When changes in state occur in the Observer, it notifies subscribers of the changes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package { import flash.events.EventDispatcher; import flash.events.Event; public class Model extends EventDispatcher { public static const UPDATE:String="inform view"; private var dirNow:Number; public function setDir(dirNow:Number):void { this.dirNow=dirNow; notify(); } public function getDir():Number { return dirNow; } protected function notify():void { dispatchEvent(new Event(Model.UPDATE)); } } } |
The static construct UPDATE is a string with any value. (I used “inform view” to remind us that it’s the View instance that uses the data from the Model.) When the direction is re-set by a call to setDir() by the Controller, it informs the View of the change. The static attribute assigns the constant to a member of the class rather than of an instance of the class. In that way you can use a self-reference to the event through Model.UPDATE within the Model class.
View
The View class probably should have an interface in the form of either an abstract class or interface. However, we’ll save that for Part IV of the discussion of MVC. The reason for an interface is that we’re likely to implement more than a single view. (The Gang of Four show three different possible views in their brief MVC discussion.) For now, we’ll just settle for a good understanding of the role of the View class in the MVC.
The view refers to the view of the data from the model. The Model data is set through the Controller sending it values from the UI. The View is notified when the data changes and requests the new data by a call to the Model’s getter. The View displays that data any way it wants, and in this case its through an analog compass. The values 0 to 360 are passed to the rotation property of a Sprite object representing the compass needle.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | package { import fl.controls.Slider; import fl.events.SliderEvent; import flash.display.Sprite; import flash.events.Event; public class View { private var model:Model; private var controller:Controller; private var base:Sprite; private var compassRose:Sprite; private var pointer:Sprite; private var slider:Slider; public function View(model:Model, controller:Controller, vessel:Sprite) { this.model=model; this.controller=controller; this.base=createAnalog(vessel); } function createAnalog(vessel:Sprite):Sprite { //add compass rose and needle compassRose=new CompassRose(); compassRose.x=250,compassRose.y=250; vessel.addChild(compassRose); pointer=new Pointer(); pointer.x=0,pointer.y=0; compassRose.addChild(pointer); //add slider var slideHolder=new Sprite(); vessel.addChild(slideHolder); slider=new Slider(); slider.maximum=360; slider.width=slider.maximum; slideHolder.addChild(slider); slider.x=(250) - (slider.width/2); slider.y=20; slider.addEventListener(SliderEvent.CHANGE, controller.newDirection); return compassRose; } public function update(e:Event):void { pointer.rotation=model.getDir(); } } } |
The Slider object has an event listener that reacts to changes in the Slider’s value property. When it changes, it calls a Controller method that passes on that value to the Model. That change sets off an update event that fires a View function to move the pointer to the changed position of the Model.
Controller
Finally, we come to the Controller. It’s job is to define the way the user interface reacts to the user input. In this case, it waits for a SliderEvent and uses the Slider.value (e.target.value) to update the Model’s current value. That’s it! It’s job is very simple.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package { import fl.events.SliderEvent; public class Controller { var model:Model; public function Controller(model:Model) { this.model=model; } public function newDirection(e:SliderEvent):void { var dirNow=e.target.value; model.setDir(dirNow); } } } |
Going Next Door Around the World
Back in the old days, hackers idea of a good time was to tap into the phone system and see if they could call the house next door by routing the call around the world. With this example of the MVC, that may have seemed to be what we did. Starting with the View, the program sends a message to the Controller, which changes the state of the Model which is used by the View to rotate the compass needle. Of course, the purpose is not to convolute a perfectly simple operation but rather to create a design that is wide open for change and update. The purpose of the MVC as used by the Gang of Four is to help you see what we mean by the term “pattern.” So rather than looking for the shortest distance between two points, you should do as GoF suggests—look to see how pattern is used. In the next installment, we should be able to see it even more so as we add a new view to the MVC. (The wait for Part IV will not be long because design patterns are easy to update and change, remember?)

The Truckin’ Through ActionScript 3.0 MVC: Part III—An Analog Compass by William B. Sanders, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.
Related posts:

Bill Sanders
Thank you, very helpful post!
I know the MVC from the PHP prespective, which is pretty different ;)
Hi Yarden,
I’d be very interested in hearing what you have to say about the MVC (and other Design Patterns) from the PHP perspective. I’ve worked with PHP for years, and I really like the language, and Chandima and I have begun some work on DPs and PHP.
What would you say is the main difference between the MVC in PHP and ActionScript 3.0? Take a look at Part IV of this MVC series and see if that increases or reduces the difference between PHP and ActionScript 3.0 use of MVC.
Thanks and hope to hear from you more,
Bill
Hi Bill,
thank you for this Tutorial! Good introduction to MVC.
But I have one question: What if I don’t use a Slider, but a TextField and a Button, to change a value of the model? Then I can’t get the value through the event’s target, can I ?
Best
W.
Hi Wolle,
A text field would work fine using a button and MouseEvent. Just change the event handler function (newDirection) to the following:
It’s just data and how it gets to the compass shouldn’t matter.
Kindest regards,
Bill
But it is not possible to get myText.text when you are in the controller.
Otherwise, if the function newDirection is of the view, you manipulate the model directly from the view, so the controller doesn’t make any sense to me.
Sorry if I mix up something cause I’m very new to MVC and perhaps didn’t really get it.
Hi Wolle,
I see what you mean. Take a look at the Mouse properties and see if you can slip in a value in one of its properties from the TextField–using one of the Focus events to pass it to the button and then on to an event handler in the Controller.
I’m pretty sure you can do it, but it will take can artful dodging and might be a little hacky. It sounds like a fun little project, though. If I have time, it’s something that I’ll play around with, but don’t let me have all the fun!
Take care,
Bill
Can you please explain the Client in more detail? And can the client be composed of more than MVC? Could the client ever be part of it’s own MVC triad and even if it could, would it make sense to do that? Or is the client just a class that utilizes other MVCs?
Thanks!
Hi Kerry,
For me, the Client class is always the class that makes requests. Sometimes the Client is part of the design pattern (shown in the class diagram), sometimes it is implied (shown in the class diagram as ‘ghosted’ in gray), and sometimes you don’t see it at all in the diagram.
Strictly speaking, the MVC is not part of the original set of design patterns. Rather, I see it as a heuristic device to help understand design patterns. However, since the publication of the Gang of Four’s book, it seems to have taken on a life of its own and developers use it for different things. (Chandima is the real MVC expert.)
Most programmers seem to use the name Main for their Client class—I have as well on occasion. So if you look at some MVCs, dig up Main.as and you’ll probably be seeing what GoF reference as the Client. You can see a good example of this with the MVC on page 436 of our book.
Let me know if this explains what you need.
Kindest regards,
Bill
Thanks for the quick response Bill.
I think if I give you a better example it’d be easier for you to answer me.
Say I have an class, let’s call it Client, that is being composed of 3 other ‘objects’, each of which is broken down into it’s own MVC triad. So would the Client class have 9 classes in total, i.e. object1Model, object1View, object1Controller, etc.??
On top of that, say when object1’s model gets updated and it has to affect object2’s view and model. I’m almost positive the Client class would be in charge of setting up the listeners as object1 would have no knowledge of object2 and vice versa.
Hopefully that makes things less broad.
Thanks again.
Hi Kerry,
Still assuming that Client is the request class, it is not composed of the other classes; it makes requests from them. The difficulty for me is that the MVC does not show any particular relationship to a Client class in a class diagram outside of those that are made by developers. In Figure 2 above, my Client used MVC objects, but that is not part of a design pattern. Rather, it’s how I decided to use the MVC for that particular application. Now, compare that with say the Proxy pattern. The Proxy shows where the Client is implied and the relationship it holds with the Subject participant.
If I’m not mistaken, you want to use the Client to attend to several different chores that you do not see as belonging to the M, V or C. In this particular case, I believe that the View would be in charge of setting up listeners; so no, that would not be the job of the Client.
The best summary of the jobs of the MVC is the one Chandima did on page 429. Everything is broken down for you. Take a look at it, and let me know if that helps more than I did (or failed to do!).
Kindest regards,
Bill