实现IEventDispatcher的类不能使用Event元数据标记

时间:2011-05-04 14:51:34

标签: flex events metadata

好的Flex专家,我们有以下课程

package
{
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.IEventDispatcher;

    import mx.controls.Alert;
    import mx.core.IMXMLObject;

    [Event(name="progressReady", type="flash.events.Event")]
    public class IndependentClass implements IMXMLObject, IEventDispatcher{
            public var dispatcher:IEventDispatcher;

            public function initialized(document:Object, id:String):void{
                    dispatcher = document as EventDispatcher;
                    addEventListener("progressReady", progressReadyListener);
            }

            public function progressReadyListener(e:Event):void{
                    Alert.show("progressReadyListener inside");
            }

            public function click():void{
                    dispatchEvent(new Event("progressReady", true));
            }

            public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void{
                    if(dispatcher != null){
                            dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
                    }
            }

            public function dispatchEvent(event:Event):Boolean{
                    if(dispatcher != null){
                            return dispatcher.dispatchEvent(event);
                    }
                    return false;
            }

            public function hasEventListener(type:String):Boolean{
                    if(dispatcher != null){
                            return dispatcher.hasEventListener(type);
                    }
                    return false;
            }

            public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void{
                    if(dispatcher != null){
                            dispatcher.removeEventListener(type, listener, useCapture);
                    }
            }

            public function willTrigger(type:String):Boolean{
                    if(dispatcher != null){
                            return dispatcher.willTrigger(type);
                    }
                    return false;
            }
       }

    }

我们遵循MXML标记:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
           xmlns:s="library://ns.adobe.com/flex/spark" 
           xmlns:mx="library://ns.adobe.com/flex/mx" 
           xmlns:local="*">

<fx:Script>
    <![CDATA[
        import mx.controls.Alert;
        protected function progressHandler():void{
            Alert.show("progressHandler outside");
        }
    ]]>
</fx:Script>

<fx:Declarations>
    <local:IndependentClass id="ic" progressReady="progressHandler()"/>
</fx:Declarations>

<s:Button click="{ic.click()}"/>
</s:Application>

如果您运行这些,您会注意到MXML组件无法听到该事件。问题很简单,是否有一些方法可以使Event-metadata标签无法扩展EventDispatcher?我想保持这个类独立,并尽可能使用对象组合。

不,我不想在MXML文件中使用ActionScript addEventListener。它不会告诉开发人员任何好的旧事件元数据标记,此外,这不是这个例子的重点。 :)

希望有人可以启发事件元数据标签在窗帘后面的作用。

2 个答案:

答案 0 :(得分:0)

  

事件元数据标记可以正常工作   扩展EventDispatcher

据我所知,事件元数据标签只做两件事。它告诉代码暗示组件可以调度事件;或者它用于生成ASDocs。我希望你能够在不扩展EventDispatcher的情况下使用元数据标签;但是我不相信你的组件能够在不扩展EventDispatcher或创建自己的Event Dispatcher系统的情况下调度事件。我认为AS3 Signals是另一种事件调度系统。

  

我不想使用ActionScript   MXML文件中的addEventListener。它   并没有告诉开发者什么   就像旧的事件元数据标签一样,

addEventListener方法是一种向组件添加事件侦听器的方法 元数据标签是一种告诉代码提示该组件可以调度事件的方法 它们服务于不同的目的;并且使用一个并不否定对另一个的需要。

我相信这可以解决您的问题。我个人的方法是在类需要调度事件时扩展EventDispatcher。

答案 1 :(得分:0)

确定。为了让你的代码工作,你应该改变你的主类,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:local="*" xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="init()">

    <fx:Script>
    <![CDATA[
        import mx.controls.Alert;

        protected function progressHandler():void
        {
            Alert.show("progressHandler outside");
        }

        protected function init():void
        {
            addEventListener("progressReady", progressReadyHandler);
        }

        private function progressReadyHandler(event:Event):void
        {
            progressHandler();
        }
    ]]>
    </fx:Script>

    <fx:Declarations>
        <local:IndependentClass id="ic" />
    </fx:Declarations>

    <s:Button click="{ic.click()}" />
</s:Application>

问题是你没有设置正确调度事件的对象。在您的情况下,此对象仍然是主应用程序类。为了实现您的目标,您应该重新创建IndependentClass,如下所示:

package
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;

import mx.controls.Alert;

[Event(name="progressReady", type="flash.events.Event")]
public class ProperIndependentClass implements IEventDispatcher
{
    public function ProperIndependentClass()
    {
        // This line initialized dispatching making this object target and currentTarget of the event
        dispatcher = new EventDispatcher(this);
        addEventListener("progressReady", progressReadyListener);
    }

    private var dispatcher:EventDispatcher;

    public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0,
                                     useWeakReference:Boolean = false):void
    {
        dispatcher.addEventListener(type, listener, useCapture, priority);
    }

    public function click():void
    {
        dispatchEvent(new Event("progressReady", true));
    }

    public function hasEventListener(type:String):Boolean
    {
        return dispatcher.hasEventListener(type);
    }

    public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
    {
        dispatcher.removeEventListener(type, listener, useCapture);
    }

    public function willTrigger(type:String):Boolean
    {
        return dispatcher.willTrigger(type);
    }

    public function dispatchEvent(evt:Event):Boolean
    {
        return dispatcher.dispatchEvent(evt);
    }

    public function progressReadyListener(e:Event):void
    {
        Alert.show("progressReadyListener inside");
    }
}
}

我评论了构造函数中执行所有魔法的行。有关详细信息,请in official documentation

所以你的主要课程将如下所示:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:local="*" xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Script>
    <![CDATA[
        import mx.controls.Alert;

        protected function progressHandler():void
        {
            Alert.show("progressHandler outside");
        }
    ]]>
    </fx:Script>

    <fx:Declarations>
        <local:ProperIndependentClass id="ic" progressReady="progressHandler()" />
    </fx:Declarations>

    <s:Button click="{ic.click()}" />
</s:Application>

那么[Event] metatag怎么样?它不是编译时注释,它有助于编译器验证MXML标记属性。此元标记的另一种用法是通过IDE提供事件代码完成(当您键入addEventListener时,在MXML和ActionScript中都提供)。它在运行时没有任何影响。

P.S。杰弗里是对的,你应该扩展EventDispatcherIEventDispatcher的目的是,如果您的类继承了一些非EventDispatcher派生的其他类。在这种情况下,您可以使用组合来解决事件调度的问题。在您的情况下,IndependentClass没有任何要求不从EventDispatcher继承。