从自定义组件调度自定义事件

Posted

技术标签:

【中文标题】从自定义组件调度自定义事件【英文标题】:Dispatching custom event from a custom component 【发布时间】:2011-11-12 15:46:25 【问题描述】:

我有一个自定义 Flex 4.5 组件(用于列表)-

Game.mxml(表示纸牌游戏中可点击的游戏桌):

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer 
    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:comps="*"
      
    autoDrawBackground="false"
    creationComplete="init(event)">

    <fx:Metadata> 
        [Event(name="pref_event", type="PrefEvent")] 
    </fx:Metadata>

    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;

            private var _data:XML;

            [Bindable("dataChange")]
            public override function get data():Object 
                return _data;
            

            public override function set data(value:Object):void 
                _data = value as XML;
                if (null == _data)
                    return;

                gameid = _data.@id;

                for (var i:uint = 0; i < 3; i++) 
                    this['_user' + i].data = _data.elements('user')[i];
                

                dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
            

            public function init(event:FlexEvent):void 
                _rect.filters = Util.SHADOW;
                addEventListener(MouseEvent.CLICK, handleClick);
            

            private function handleClick(event:MouseEvent):void 
            trace("Clicked: " + gameid);
                dispatchEvent(new PrefEvent(PrefEvent.GAME_CLICKED, gameid, true));
            

            public function set gameid(str:String):void 
                _gameid.text = '#' + str;
            

            public function get gameid():String 
                return _gameid.text.substring(1);
            
        ]]>
    </fx:Script>

    <s:Rect id="_rect" x="20" y="20"   radiusX="16" radiusY="16">
        <s:stroke>
            <s:SolidColorStroke color="#4F69B5" weight="4"/>
        </s:stroke>     
        <s:fill>
            <s:SolidColor color="#CCDDEE" />
        </s:fill>
    </s:Rect>

    <s:Label id="_gameid" x="0" y="75"  fontSize="16" textAlign="center" color="#FFFFFF" />

    <comps:User id="_user0" x="56"  y="4" scaleX=".3" scaleY=".3" interactive="false" visible="false" />
    <comps:User id="_user1" x="108" y="60" scaleX=".3" scaleY=".3" interactive="false" visible="false" />
    <comps:User id="_user2" x="4"   y="60" scaleX=".3" scaleY=".3" interactive="false" visible="false" />

</s:ItemRenderer>

我正在尝试从中分派自定义事件 - PrefEvent.as

package 
    import flash.events.Event;

    public class PrefEvent extends Event 
        public var str:String;
        public static const GAME_CLICKED:String = 'game_clicked';
        public static const CARD_CLICKED:String = 'card_clicked';
        public static const CARD_PLAYED:String  = 'card_played';

        public function PrefEvent(type:String, n:String, bubbles:Boolean = false, cancelable:Boolean = false)
            super(type, bubbles,cancelable);
            str = n;
        

        public override function clone():Event 
            return new PrefEvent(type, str, bubbles, cancelable);
        

        public override function toString():String 
            return str;
        
    

最后是我的测试代码 - GameTest.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:comps="*"
      
    creationComplete="init()">

    <fx:Script>
        <![CDATA[
            public function init():void 
                game.data = <game id="8946">
                                <user id="OK353118989212"/>
                                <user id="OK351923295875"/>
                            </game>;
                   

            private function gameClicked(event:PrefEvent):void 
                trace("game clicked: " + event);
                       
        ]]>
    </fx:Script>

    <comps:Game id="game" x="0" y="0" pref_event="gameClicked(event)" />

</s:Application>

但我从来没有看到“游戏点击:”跟踪。请问有人知道为什么吗?

我可能遗漏了一些小东西,因为我可以看到“Clicked: 8946”跟踪。

【问题讨论】:

【参考方案1】:

[Event(name="pref_event", type="PrefEvent")] != new PrefEvent(PrefEvent.GAME_CLICKED, gameid, true)

事件名称不一样。

【讨论】:

对不起,我不明白? Flash Builder 似乎对 pref_event 很满意(在游戏组件的代码完成中提供了它) 这是因为您已经指定了元数据,但您的偶数名称是“pref_event”,而您正在调度的 actual 事件使用名称“game_clicked”。你看到问题了吗?【参考方案2】:

你应该把它写在你的 Game.mxml 文件中:

<fx:Metadata> 
        [Event(name="game_clicked", type="PrefEvent")] 
</fx:Metadata>

这在你的主文件中:

<comps:Game id="game" x="0" y="0" game_clicked="gameClicked(event)" />

更多信息请参见here...

【讨论】:

【参考方案3】:

问题:

Game.mxml 文件中有 "pref_event" 事件

[Event(name="pref_event", type="PrefEvent")]

但您的调度PrefEvent.GAME_CLICKED ("game_clicked")

解决方案:

您必须为此调度正确的事件。

dispatchEvent( new PrefEvent("pref_event",gameid, true) );  

【讨论】:

以上是关于从自定义组件调度自定义事件的主要内容,如果未能解决你的问题,请参考以下文章

Vue:从自定义组件派生的自定义组件中的 v-model 和输入事件

如何在 TypeScript v2.x 中从自定义 React 组件公开“通用”事件

将自定义 UIKit 事件从自定义 UIKit 控件公开到 SwiftUI

组件的调度自定义事件没有父级

从自定义控件的模板部分中删除事件处理程序

Firebase 大查询 - 如何从自定义事件表中检索数据