apache-flexactionscriptflex4mate

Actionscript Compiler directive


I have an established pattern for lazy loading data from a server via AMF.

    private var _XeventDispatched:Boolean;
    private var _X:ArrayCollection;
    public function get X():ArrayCollection{
        if(!_XeventDispatched && (_X==null || _X.length==0)){
            var evt:Event = new Event();//whatever event is need for this data member
            dispatcher.dispatchEvent(evt);
            _XeventDispatched = true;
        }
        return _X;
    }
    public function set X(ac:ArrayCollection):void{
        return _X;
    }

This way the data is not loaded from the server until it is needed. (I'm using the Mate framework by the way, so when a UI is instanciated, and the injectors fire, they call this get method in the data manager class.)

What I'd like to do is create some kind of Metadata tag, similar to [Bindable] that will add the above methods in place of a public property.

[LazyLoaded(eventName="com.myCompany.LoadX")]
public var X:ArrayCollection;

Does the compiler have any hooks for this type of extension? It would save a lot of boiler plate code that is hard to read.


Solution

  • +1 Marty you lead me to this, but its different from your solution.

    I've created a base class (BaseDataManager) that all other Mate data managers can extend from, and in that class I've added the below code:

            private var eventsDispatched:Array = new Array();
            protected function lazyLoad(value:*, eventType:String):*{
                if(!eventsDispatched[event] && (value==null || (value is IList && IList(value).length==0))){
    
                    var clazzName:String = eventType.substr(0, eventType.indexOf(":"));
                    var eventClazz:Class = Class(getDefinitionByName(clazzName));
                    var event:Event = new eventClazz(eventType);
    
                    dispatcher.dispatchEvent(event);
                    eventsDispatched[event] = true;
                }
                return value;
            }
    

    Then within each data manager, if the property is to be lazy loaded, this is their accessors:

        private var _X:ArrayCollection;
        public function get X():ArrayCollection{
            return lazyLoad(_X, XLoadEvent.LOAD_EVENT_TYPE);
        }
        public function set X(value:ArrayCollection):void{
            _X = value;
        }
    

    This way most of the ugly, hard to read code is hidden away from the dev, yet still accessible for debugging if any problems were to arise.