Apache flex Actionscript编译器指令

Apache flex Actionscript编译器指令,apache-flex,actionscript,flex4,mate,Apache Flex,Actionscript,Flex4,Mate,我有一个通过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

我有一个通过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;
    }
这样,直到需要时才从服务器加载数据。(顺便说一句,我使用的是Mate框架,所以当UI实例化时,喷油器启动,他们在data manager类中调用这个get方法。)

我想做的是创建某种元数据标记,类似于[Bindable],它将添加上述方法来代替公共属性

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

编译器对这种类型的扩展有任何挂钩吗?这将节省大量难以阅读的锅炉铭牌代码。

我想您应该使用。大概是这样的:

keep-as3-metadata+=lazyload


正如Flextra所提到的,一种选择是使用元数据的运行时反射,并围绕此构建您的框架

这类似于在dpHibernate(一个我是开发人员的Flex惰性加载框架)中实现惰性加载的方式。具体地说,为了访问getter和setter并使用钩子拦截它们以进行延迟加载,我们使用
[Managed]
元标记和,它让编译器为您构建钩子

这有点像黑客,但可能会对你有所帮助。(我们已经在这项技术的基础上构建了一个非常成功的框架)

或者,您可以编写自己的编译器扩展,使用元数据,并执行AST修改以生成代码。然而,这不是为胆小的人准备的

尽管这些扩展的钩子已经存在很多年了,但是关于如何实现它却很少,您需要通过查看现有的源代码来解决它

幸运的是,Adobe的boffin在编译器扩展方面吃了他们自己的狗粮,Flex 4的一些特性(如蒙皮)已经实现为编译器扩展,为您提供了更多的示例

此处提供了编译器的源代码。。作为一个很好的起点,看一看这个项目的代码可能会有所收获


或者,看看extension,extension或[](编译器的原始开发人员Clement Wong曾经提到它是理解编译器扩展的最佳起点)。

+1 Marty您引导我到这一点,但它与您的解决方案不同

我已经创建了一个基类(
BaseDataManager
),所有其他Mate数据管理器都可以从中扩展,并且在该类中添加了以下代码:

        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;
        }
然后,在每个数据管理器中,如果要延迟加载属性,则这是它们的访问器:

    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;
    }

通过这种方式,大多数难看、难以阅读的代码都隐藏在开发人员之外,但如果出现任何问题,仍然可以进行调试。

我想用延迟加载的方法替换公共var,就像编译时用getter/setter替换[Bindable]var一样。哦,唯一要做的就是将元数据保存在已编译的SWC中。大多数框架创建者在运行时基于其自定义元数据执行此类操作。有一种方法可以深入组件以查找元数据和其他信息。如果你想改变Flex编译器的工作方式,为了根据元数据生成不同的代码,你必须改变Flex编译器。这是可行的,因为你可以得到源代码。不过我不认为它是实用的。谢谢,我希望它有某种“钩子”,但我明白你的意思,这个应用程序需要预编译,而不是运行时。@SuperSaiyen你最好使用一些ANT脚本或其他可以解析代码的构建工具,在编译之前查找元数据并进行适当的转换。这个托管元标记非常有趣,我将尝试一下,谢谢。