如何从 itemRenderer 中分派事件[Flex][翻译]

原文:How to dispatch an event from a custom item renderer

 

从 MXML 组件中分派事件并不困难,但是想要从 itemRenderer 中分派事件就没有那么直接了。下文中,我们将回顾一下这两种情况的处理方式并找出一个合适的解决方案。

 

正常情况下,当你想从 MXML 组件中分派一个事件时会使用如下的元数据标签:


<!-- 写在某个组件中 -->
<mx:metadata> [Event(name="myEvent")] </mx:metadata>

 

元数据标签让你能在另一个类中以如下方式监听事件:


<!-- 写在调用上面定义的那个组件的类中 -->
<nw:somecomponent myEvent= "onSomeEventHandler(event)" />

 

最后,当你想在组件中分派事件时可以手工的使用 dispatchEvent() 方法来分派。

 

但是如果你是想从一个作为 itemRenderer 的组件中分派事件的话会如何呢?考虑一下以下的情况:

 

在 Flex 应用程序中新建一个 List 组件。然后新建一个包含有 RadioButton 的组件用于 List 的 itemRenderer。当用户单击 RadioButton 时,可能你会想让他的父组件 List 产生一个事件。

 

但是如下的代码会产生一个编译器错误,因为 List 组件并没有“myEvent”属性:


<!-- 会产生一个编译器错误 -->
<mx:list id= "myList" dataprovider= "{listData}"
       itemRenderer= "uk.nwebb.CustomRenderer"
       myEvent= "onSomeEventHandler(event)" />

 

由于我们并没有实例化自己的 itemRenderer,如何才能获得广播出来的事件呢?要想实现这样的功能,必须通过下面的两个步骤:

 

首先,我们必须让我们分派的事件上浮,只要在方法中添加一些而外的参数就可以做到。如下设置 bubble 和 cancelable 参数:


//写在某个组件中
dispatchEvent( "myEvent" , true , true);

//由于原文比较老,上面这个写法是 Flex 2 的。Flex 3 的后面两个参数要赋到 Event 实例里面。
//Flex 3 代码如下
dispatchEvent( new Event( "myEvent" , true , true));

 

现在 List 组件仍然还是没有 myEvent 属性。为了能让 List 组件接收到上面分派的事件,我们必须确保这个 List 组件有 ID,然后可以在初始化函数或者 creattionComplete 函数中绑定事件:


//写在创建 List 组件的类中
private function onInit (): void
{
    myList . addEventListener( "myEvent" , myEventHandler);
}

 

据我所知,现在不需要在组件中加入元数据标签了,但是以防万一有一天你不是把这个组件用于 itemRenderer 而是作为一个独立的组件(正如文章开始提到的第一个情况),那些元数据标签还是需要用到的。

 

由于有读者想要一个比较完整的例子,下面这个简单的例子就是演示了如何从 itemRenderer 中分派一个事件并且响应这个事件的代码。


//写在调用 itemRenderer 的类中:
public function onComplete():void{
        list1.addEventListener("radioButtonClicked", itemRendererRadioButtonClickHandler);
}

//你的 itemRenderer 类:
<mx:Canvas xmlns:mx= "http://www.adobe.com/2006/mxml" height= "100%" initialize= "onInit();" >
    <!-- ****************************************************************************
      Keep the RadioButton and Label separate so that the label can be clicked without
      selecting the RadioButton (eg - to display further info on the item).
    ****************************************************************************** -->

    <mx:Metadata>
        [Event(name="radioButtonClicked")]
    </mx:Metadata>

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

            [Bindable] public var thisIcon:String;

            public function onInit():void{
                addEventListener(FlexEvent.DATA_CHANGE, onDataChanged, false, 0, true);
            }

            private function onDataChanged(event:FlexEvent):void{
                if(data != null){
                    var name:String = data.name;
                    var id:String;
                    if(data.id == null || data.id == ""){
                        id = " (creates a new " + data.type.name + " entity)";
                    }
                    if(data["type"]!= null){
                        thisIcon = data.type.smallIconUrl;
                    }else{
                        thisIcon = "assets/icons/16x16/help2.png";
                    }
                    label1.text = name + id;
                }
            }

            private function rbClickHandler():void{
                dispatchEvent(new Event("radioButtonClicked", true, true));
            }
        ]]>
    </mx:Script>
    <mx:HBox>
        <mx:RadioButton id= "radioButton" labelplacement= "left" click= "rbClickHandler();" >
                <mx:Image id= "theIcon" source= "{thisIcon}" >
                        <mx:label id= "label1" />
                        </mx:Image>
               </mx:RadioButton>
         </mx:HBox>
</mx:Canvas>

 

 

 

你可能感兴趣的:(list,function,String,Flex,编译器,RadioButton)