Adding A Controller


Up to this point we've only really seen models and views, but no controllers. Next we'll look at how to add a controller. A controller should be the way in which the system or user can change the view or model.

In our clock example we now have two views and one model. If we want to be able to control the views (toggle between views, for instance) or the model (setting the value) then we need to add a controller. In our example we'll create a controller called Clock. The Clock controller allows us to specify a model and one or more views. It then adds user interface controls that allow the user to set the model value and toggle between the views. The Clock class is written as follows:

package com.peachpit.aas3wdp.mvcexample.controllers {    import flash.display.Sprite;    import flash.text.TextField;    import flash.text.TextFieldType;    import flash.events.MouseEvent;    import flash.events.Event;    import com.peachpit.aas3wdp.mvcexample.data.Time;    import com.peachpit.aas3wdp.mvcexample.data.ClockData;    import com.peachpit.aas3wdp.mvcexample.clock.AbstractClockView;    // Note that you'll need to include the AAS3WDP library to your     // project's source path for this class.    import com.peachpit.aas3wdp.controls.BasicButton;    public class Clock extends Sprite {       private var _hours:TextField;       private var _minutes:TextField;       private var _seconds:TextField;       private var _clockData:ClockData;       private var _viewIndex:int;       private var _views:Array;       private var _toggleView:BasicButton;       // The controller has one model. It listens for updates to       // the model.       public function set data(value:ClockData):void {          _clockData = value;          _clockData.addEventListener(Event.CHANGE,           onModelUpdate);          onModelUpdate();       }       public function Clock() {          // The controller can store references to one or           // more views.          _views = new Array();          // Create three input text fields.          _hours = createField();          _minutes = createField();          _seconds = createField();          _minutes.x = 45;          _seconds.x = 90;          // Create a button that will allow the user to           // toggle between views.          _toggleView = new BasicButton("Toggle View");          _toggleView.addEventListener(MouseEvent.CLICK,          toggleView);          addChild(_toggleView);          _toggleView.x = 135;       }           // Add AbstractClockView instances to the _views array.       public function addView(view:AbstractClockView):void {          _views.push(view);          // If this is the first view added then add it to           // the display list by default.          if(_views.length == 1) {             addChild(view);             _viewIndex = 0;          }          // Make sure the view appears just below the input           // text fields.          view.y = 40view.getBounds(view).top;          view.x = -view.getBounds(view).left;       }       private function createField():TextField {          var field:TextField = new TextField();          field.width = 40;          field.height = 22;          field.border = true;          field.background = true;          field.restrict = "0-9";          field.type = TextFieldType.INPUT;          // Listen for focusOut events on each text field.          field.addEventListener(FocusEvent.FOCUS_OUT,            onFocusChange);          addChild(field);          return field;       }       // When the focus changes for a text field update the model       // to correspond to the user input.        private function onFocusChange(event:FocusEvent):void {          if(event.target.length < 1) {             event.target.text = 0;                 }          var time:Time = new Time(uint(_hours.text), uint(_minutes.text),  uint(_seconds.text));          _clockData.time = time;       }       // Remove the current view, and add the next view in the        // array.       private function toggleView(event:MouseEvent):void {          removeChild(_views[_viewIndex]);          _viewIndex++;          if(_viewIndex >= _views.length) {             _viewIndex = 0;          }          addChild(_views[_viewIndex]);       }       // When the model changes update the text field values.       private function onModelUpdate(event:Event = null):void {          // Use if statements so that the text values don't           // change if the user is currently changing the           // value in a text field.          if(stage != null) {             if(stage.focus != _hours) {                _hours.text = _clockData.time.hour.toString();             }             if(stage.focus != _minutes) {                _minutes.text = _clockData.time.minute.toString();             }             if(stage.focus != _seconds) {                _seconds.text = _clockData.time.second.toString();             }          }     }        }    }


Now you can use a Clock instance as follows.

package {    import flash.display.Sprite;    import flash.display.StageAlign;    import flash.display.StageScaleMode;    import com.peachpit.aas3wdp.mvcexample.data.ClockData;    import com.peachpit.aas3wdp.mvcexample.clock.AbstractClockView;    import com.peachpit.aas3wdp.mvcexample.clock.AnalogClock;    import com.peachpit.aas3wdp.mvcexample.clock.DigitalClock;    import com.peachpit.aas3wdp.mvcexample.controllers.Clock;    public class ClockTest extends Sprite   {       private var _clockData:ClockData;       public function ClockTest() {                    stage.align = StageAlign.TOP_LEFT;          stage.scaleMode = StageScaleMode.NO_SCALE;                    _clockData = new ClockData();          _clockData.realTime = true;                    var clock:Clock = new Clock();          clock.data = _clockData;          addChild(clock);                    var view:AbstractClockView = new            DigitalClock(_clockData);          clock.addView(view);                    view = new AnalogClock(_clockData);          clock.addView(view);                 }        } }


In this version the Clock instance is the controller by which the user can toggle between views and adjust the value of the model.




Advanced ActionScript 3 with Design Patterns
Advanced ActionScript 3 with Design Patterns
ISBN: 0321426568
EAN: 2147483647
Year: 2004
Pages: 132

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net