组件问题中的另一个Flex自定义事件

时间:2011-02-03 22:36:40

标签: flex events flex4 custom-component

我似乎无法获得在Flex 4中工作的事件的最基本用途之一。我已经遵循了多个教程并且随处可见。从我所知道的,我做的一切都是正确的,所以某处肯定会有一些愚蠢的错误。

我有一个包含按钮的主应用程序文件。单击该按钮时,它会触发一个自定义事件,我希望我的子组件中的侦听器能够捕获。事件正在解雇。子组件事件侦听器未捕获该事件。不知道为什么。自定义事件从Adobe's tutorial复制粘贴(减去自定义命名空间和注释)。

主要申请

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                       xmlns:s="library://ns.adobe.com/flex/spark" 
                       xmlns:mx="library://ns.adobe.com/flex/mx"
                       applicationComplete="init()" xmlns:local="*">
    <fx:Metadata>
        [Event(name="enableChanged", type="EnableChangeEvent")]
    </fx:Metadata>

    <fx:Script>
        <![CDATA[
            import EnableChangeEvent;
            import TestComponent;

            private function doDispatchEvent(event:MouseEvent):void {
                if(dispatchEvent(new EnableChangeEvent(EnableChangeEvent.ENABLE_CHANGED, true)))
                {
                    statusLabel.text = "Event was dispatched";
                }
            }

            public function init():void {
                myButton.addEventListener(MouseEvent.CLICK, doDispatchEvent);
            }
        ]]>
    </fx:Script>

    <s:Button x="95" y="83" label="Button" id="myButton" />
    <s:Label x="230" y="83" text="" id="statusLabel" />
    <local:TestComponent x="95" y="150" width="300" height="400" />
</s:WindowedApplication>

子组件(测试)

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx"
         width="100%" height="100%"
         initialize="init();">

    <fx:Script>
        <![CDATA[
            import EnableChangeEvent;

            private function doFinalAction(event:EnableChangeEvent):void {
                myLabel.text = "Custom Event Recieved";
            }

            private function init():void {
                addEventListener(EnableChangeEvent.ENABLE_CHANGED, doFinalAction);
            }
        ]]>
    </fx:Script>

    <s:Label width="300" height="50" text="Should change on click" id="myLabel" />
</s:Group>

自定义事件(来自Adobe)

package {
    import flash.events.Event;

    public class EnableChangeEvent extends Event
    {
        public function EnableChangeEvent(type:String, isEnabled:Boolean=false) {
            super(type);
            this.isEnabled = isEnabled;
        }

        public static const ENABLE_CHANGED:String = "enableChanged";
        public var isEnabled:Boolean;

        override public function clone():Event {
            return new EnableChangeEvent(type, isEnabled);
        }
    }
}

3 个答案:

答案 0 :(得分:2)

Timofei Davydik的回答是正确的。由于Application对象调度事件,如果您希望TestComponent对象捕获它,则必须在Application内的TestComponent对象的引用中添加一个侦听器。 }。您可以使用TestComponent对象的继承属性“parentApplication”来获取对Application对象的引用。

在TestComponent.mxml中更改以下代码:

private function init():void 
{     
    this.parentApplication.addEventListener(EnableChangeEvent.ENABLE_CHANGED, doFinalAction);  

}// end function 

<强> [UPDATE]

就个人而言,我觉得你要以错误的方式使用事件,所以我做了一个类似的flex应用程序来演示如何在flex中使用事件。

Main.mxml

<?xml version="1.0" encoding="utf-8"?>

<s:WindowedApplication 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:components="components.*"
                       xmlns:events="events.*"
                       applicationComplete="init()">

    <fx:Script>
        <![CDATA[

            import events.EnableChangeEvent;

            public function init():void
            {     
                label1.text = "Application Complete!";

            }// end function

            private function onTestButtonEnableChanged(e:EnableChangeEvent):void
            {                     
                label2.text = "Enabled = " + e.isEnabled;   

            }// end function

        ]]>
    </fx:Script>

    <s:layout>
        <s:VerticalLayout horizontalAlign="center" paddingTop="50" />
    </s:layout>

    <components:TestButton id="testButton" label="CLICK!" enableChanged="onTestButtonEnableChanged(event)"  />
    <s:Label id="label1"/> 
    <s:Label id="label2"/>

</s:WindowedApplication>

TestButton.mxml

<?xml version="1.0" encoding="utf-8"?>

<s:Button xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx"
          click="onClick()">

    <fx:Metadata>
        [Event(name="enableChanged", type="events.EnableChangeEvent")]
    </fx:Metadata>

    <fx:Script>

        <![CDATA[

            import events.EnableChangeEvent

            private var isEnabled:Boolean;

            private function onClick():void
            {
                isEnabled = !isEnabled;

                dispatchEvent(new EnableChangeEvent(EnableChangeEvent.ENABLE_CHANGED, isEnabled));

            }// end function

        ]]>

    </fx:Script>

</s:Button>

应用程序之间的主要区别在于Button对象(在本例中为TestButton对象)在单击时调度EnableChangeEvent事件。在调度事件时,我们可以将_isEnabled TestButton属性的布尔值解析为事件。之前,使用行isEnabled = !isEnabled反转该值。现在我们可以使用带有xml属性TestButton的{​​{1}}对象的mxml声明来处理事件。

也可以尝试一本我正在阅读的书,而不是按照教程。它被David Gassner称为“Adobe Flash Builder 4和Flex 4 Bible”,您可以将其作为平装书或书籍获取。

答案 1 :(得分:1)

@Taurayi是正确的,但为了让您只使用一次更改来处理当前代码,请编辑Test Component的init,如下所示:

private function init():void 
{ 
     FlexGlobals.topLevelApplication.addEventListener(EnableChangeEvent.ENABLE_CHANGED, doFinalAction);
}

答案 2 :(得分:0)

您的应用程序对象调度自定义事件。为什么你希望你的团队“抓住”这个活动?它不会。自定义事件既没有捕获也没有冒泡阶段。因此,只有添加到应用程序对象的侦听器才会收听此事件。