/** * Web App Solution Confidential Information * Copyright 2010, Web App Solution, Inc. * * @date April, 15, 2010 */ package com.webappsolution.mediator { import com.webappsolution.logging.LocalConnectionLog; import com.webappsolution.model.IAppModel; import flash.events.Event; import flash.events.IEventDispatcher; import mx.core.UIComponent; import mx.events.FlexEvent; import mx.logging.ILogger; /** * The base class for all view mediators. It's most useful function is to * provide the metadata and setter method to inject the corresponding view into * the mediator. * *

* In addition, it allows concrete View Mediators to add view event handlers * and data bindings to children of the corresponding View with confidence by * by determining if the view is "alive" (aka has been instantiated and added to * the stage -- creationComplete event fired) or if it needs to listen for it's * creation complete event before performing actions on it. See the * public function setView( value:* ):void method for more * details on this. *

*/ public class AbstractViewMediator { /** * Logger. */ private static const logger:ILogger = LocalConnectionLog.getLogger(AbstractViewMediator); /** * A flag indicating if the correpsonding view's creation complete has fired. */ public var isViewCreationComplete:Boolean = false; /** * The view class we're injecting into the view mediator. */ protected var viewType:Class; /** * The view that corresponds to this view mediator. */ protected var _view:UIComponent; /** * Constructor. */ public function AbstractViewMediator(viewType:Class) { super(); logger.debug("Constructor"); this.viewType = viewType; } /** * Allows this class to dispatch events. The event dispatcher is * injected by Swiz due to the [Dispatcher] metadata and the class * memeber's type of IEventDispatcher. */ [Dispatcher] public var dispatcher:IEventDispatcher; /** * Instruct Swiz to Inject the ApplicationModel by type. */ [Inject] public function set appModel(value:IAppModel):void { logger.debug("AUTOWIRE :: appModel = " + value); this._appModel = value; } public function get appModel():IAppModel { return this._appModel; } private var _appModel:IAppModel; /** * Listen for views added to the stage and determine if it's the corresponding * View for this View Mediator. This check is done by looking at the view added * to the stage and do a simple compare on the viewType:Class class * member that we set in concrete View Medators via their constructors. * *

* Also determine if the View has fired its creation complete event so developers * can perform actions on the view from the View Mediator without hitting null pointers * for uninstantiated objects in the View. If the creation complete has not fired, then * listen for it. *

*/ [Mediate( "flash.events.Event.ADDED_TO_STAGE", properties="target", useCapture="true" )] public function setView(value:*):void { if(value is viewType) { logger.debug("AUTOWIRE :: view = " + value); this._view = value; // determine if the view has been initialized... // NO...listen for it;s creation complete event if(this._view.initialized == false) { this._view.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete); } // YES...call the init() method to kick off the instation of the view mediator else { this.isViewCreationComplete = true; this.init(); } // don't get in GC's way if the view is removed this._view.addEventListener(Event.REMOVED_FROM_STAGE, cleanup); } else { // logger.warn("Don't inject the view " + value); } } /** * The init() method is only called when the ViewMediator's corresponding * View's creationComplete has been fired; this allows developers to add event listens, * data bindings, and any other view functions in confidence (without worry about accessing * children of the view that are null and cause runtime errors.) * *

* Developers can override this to perform additional initializaitons in their ViewMediator, * but must call super.init() in order for the aforementioned to function * correctly. *

* *

* Does not have to be overriden. Simple here for convenience and as a marker method *

*/ protected function init():void { logger.debug("init"); this.setViewListeners(); this.setViewDataBindings(); } /** * Set the listeners for the UI components on the stage for the ViewMediator's corresponding View. * *

* Does not have to be overriden. Simple here for convenience and as a marker method *

*/ protected function setViewListeners():void { logger.debug("setViewListeners"); // OVERRIDDEN } /** * Set the data bindings for the UI components on the stage for the ViewMediator's corresponding View. * *

* Does not have to be overriden. Simple here for convenience and as a marker method *

*/ protected function setViewDataBindings():void { logger.debug("setViewDataBindings"); // OVERRIDDEN } /** * Listen for the creation complete of the View for this ViewMediator. */ protected function onCreationComplete( event:FlexEvent ):void { logger.debug("onCreationComplete"); this.isViewCreationComplete = true; this._view.removeEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete); this.init(); } /** * Remove any listeners we've created. * *

* Developers should override this method to remove any custom listners * created in the concrete ViewMediator. Developers must call * super.cleanup() in order for this to function correctly. *

*/ protected function cleanup( event:Event ):void { logger.debug("cleanup"); this._view.removeEventListener(Event.REMOVED_FROM_STAGE, cleanup); } } }