通过[Event]元数据,开发者可以为组件定义事件,将组建和自定义事件关联起来,编译器能够把这些自定义的事件识别为组件属性(将事件名称作为组件的一个属性)
使用[Event]元数据的签名如下:
Event(name="eventName",type="package.eventType")]
name说明了事件的名称,而type表明了该名称对应的事件类型,事件侦听器使用name进行注册。可以为ActionScript组件和MXML组件定义定义事件。
为ActionScript组件定义事件,[Event]元数据必须置于包(package)定义之内,类(class)定义之上,如下所示:
package com.esri.comm
{
import spark.components.Button;
//将事件和组件关联起来
[Event(name="load",type="com.esri.comm.AppEvent")]
public class But extends Button
{
public function But()
{
//TODO: implement function
super();
}
}
}
------------------------------------------------------------------------------------------------
自定义事件和事件派发
自定义事件:
package com.esri.comm
{
import flash.events.Event;
//自定义一个事件
public class AppEvent extends Event
{
public static const ERROR:String = "eror";
public static const LOAD:String = "load";
//type:事件类型
public function AppEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}
<?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" minWidth="955" minHeight="600"
xmlns:components="com.esri.comm.*" creationComplete="init()">
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.esri.comm.AppEvent;
//application的初始化
private function init():void{
//调用addEventListener可将事件监听器注册到对象,其中but1_appEventHandler为事件监听器,此处监听类型为load的AppEvent
this.addEventListener("load",but1_appEventHandler,true); //Application的对象text监听load事件,并在捕获阶段监听
panel1.addEventListener(AppEvent.LOAD,but1_appEventHandler,true);//Panel的对象panel1监听load事件,并在捕获阶段监听
buttn1.addEventListener(AppEvent.LOAD,but1_appEventHandler,false);//Button的对象buttn1监听load事件,并在目标阶段监听,因为buttn1是目标对象
//调用addEventListener可将事件监听器注册到对象,其中but1_appEventHandler为事件监听器,此处监听类型为error的AppEvent
this.addEventListener("error",but1_appEventHandler2,true); //Application的对象text监听load事件,并在捕获阶段监听
panel1.addEventListener(AppEvent.ERROR,but1_appEventHandler2,true);//Panel的对象panel1监听load事件,并在捕获阶段监听
buttn2.addEventListener(AppEvent.ERROR,but1_appEventHandler2,false);//Button的对象buttn2监听load事件,并在目标阶段监听,因为buttn2是目标对象
}
//当发生事件时,AppEvent对象将作为参数传递给事件侦听器
private function but1_appEventHandler(event:AppEvent):void
{
//currentTarget:当前正在使用某个事件侦听器处理Event的对象
trace("load:"+event.currentTarget);
}
//当发生事件时,AppEvent对象将作为参数传递给事件侦听器
private function but1_appEventHandler2(event:AppEvent):void
{
//currentTarget:当前正在使用某个事件侦听器处理Event的对象
trace("error:"+event.currentTarget);
}
private function dispatchAppEvent(event:MouseEvent):void
{
//调用dispatchEvent方法派发事件的对象为目标对象,由flash player派发一个事件至目标对象buttn1
buttn1.dispatchEvent(new AppEvent("load",false,false)); //不冒泡,即显示列表中的对象都可以监听到该事件
}
private function dispatchAppEvent2(event:MouseEvent):void
{
//调用dispatchEvent方法派发事件的对象为目标对象,由flash player派发一个事件至目标对象buttn2
buttn2.dispatchEvent(new AppEvent("error",false,false)); //不冒泡,即显示列表中的对象都可以监听到该事件
}
]]>
</fx:Script>
<s:Panel x="290" y="52" width="321" height="313" id="panel1" title="Panel">
<s:Button id="buttn2" label="由buttn2触发类型为error的AppEvent事件" click="dispatchAppEvent2(event)" x="10" y="125" height="32" width="234"/>
<s:Button id="buttn1" label="由buttn1触发类型为load的AppEvent事件" click="dispatchAppEvent(event)" x="10" y="47" height="32" width="234"/>
</s:Panel>
</s:Application>
通过dispatchEvent方法触发事件后,将事件调度到事件流中,然后Flash Player会在事件流中检查显示列表中的每个节点对象是否注册了事件侦听器,如果注册了,则调用事件侦听器来完成针对事件的响应处理。
这里强调下几个概念:
一、事件的派发者(也就是目标对象):调用dispatchEvent方法派发事件的对象,只有EventDispatcher或其子类才能派发事件。
事件监听者:调用addEventListener方法监听事件的对象,只有显示列表中的对象才能捕获到事件,在监听的时候如果监听者不是目标对象,需要将addEventListener方法中的第三个参数即useCapture设置为true,也就是在捕获阶段监听事件。
备注:
Event 类作为创建 Event 对象的基类,当发生事件时,Event 对象将作为参数传递给事件侦听器。
EventDispatcher 类允许”显示列表”上的任何对象都是一个事件目标。在概念上,到事件目标的此往返行程被划分为三个阶段:
捕获阶段包括从根到事件目标节点之前的最后一个节点的行程;
目标阶段仅包括事件目标节点;
冒泡阶段包括回程上遇到的任何后续节点到显示列表的根,但不包括目标节点。