Apache flex 实现IEventDispatcher的类不能使用事件元数据标记

Apache flex 实现IEventDispatcher的类不能使用事件元数据标记,apache-flex,events,metadata,Apache 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

好的,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组件无法听到事件。问题很简单,是否有某种方法可以让事件元数据标记在不扩展EventDispatcher的情况下工作?我希望保持这个类的独立性,并尽可能多地使用对象组合

不,我不想在MXML文件中使用ActionScript addEventListener。它不会告诉开发人员任何东西,比如好的旧事件元数据标记,而且,这不是本例的重点。:)

希望有人能了解事件元数据标签在幕后的作用

事件元数据标记在没有 扩展EventDispatcher

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

我不想使用ActionScript 在MXML文件中添加EventListener。信息技术 没有告诉开发者任何事情 就像旧事件元数据标签一样

addEventListener方法是向组件添加事件侦听器的一种方法。
元数据标记是一种告诉代码暗示此组件可能发送事件的方法。
它们的用途非常不同;使用其中一个并不能否定对另一个的需求


我相信这解决了你的问题。我个人的方法是在类需要分派事件时扩展EventDispatcher

好的。要使代码正常工作,ypu应更改主类,如下所示:

<?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>
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");
    }
}
}
<?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>
我已经在构造函数中注释了执行所有魔术的行。更多详情可供查阅

因此,您的主要类将如下所示:

<?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>
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");
    }
}
}
<?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]
元标记呢。它只是一个编译时注释,帮助编译器验证MXML标记属性。此元标记的另一个用途是通过IDE提供事件代码完成(在您键入
addEventListener
时,在MXML和ActionScript中)。它在运行时没有任何影响


另外,Jeffry说得对,你应该扩展
EventDispatcher
IEventDispatcher
的用途是,如果您的类继承了一些其他类,而这些类不是从
EventDispatcher
派生的。在这种情况下,您可以使用composition来解决事件调度问题。在您的情况下,您的
IndependentClass
没有任何不从
EventDispatcher
继承的要求。嘿,谢谢您的回复。我知道addEventListener和事件元数据的用例。我试图指出的一点是,事件元数据直接告诉最终开发人员(组件用户)组件分派的是什么类型的事件(它们显示在IDE中),而addEventListener没有(您必须查看文档)。作为后续问题,您是否看到扩展EventDispatcher比像Constantiner那样编写它有什么好处(您还没有提到)?有什么陷阱吗?@Jukka Hämäläinen你的话是真的;但我真的不明白你的意思。我还可以说,“事件元数据直接告诉组件用户组件分派的是什么类型的事件;但是使用createChildren方法则不然。”这样的说法是正确的;但仍然比较完全不相关的项目。除此之外;组合似乎比继承更好地使用封装。但是,我对此没有进一步的想法。