Flex EventDispatcher类

 

事件当然要发生在事件目标上,比如点击按钮时,事件目标就是按钮。在Flex应用中,任何显示列表上的对象都可能成为事件目标,换句话说,都能够触发事件。而这种特性全拜flash.events.EventDispatcher类所赐。

EventDispatcher类实现IEventDispatcher接口,并且是DisplayObject类的基类(DisplayObject 类是可放在显示列表中的所有对象类的基类)。EventDispatcher类允许显示列表上的任何对象都是一个事件目标,而同时,又使得这些对象能够侦听事件。

对于EventDispatcher类来说,“dispatcher(调度)”不是一个好名字,因为EventDispatcher类不仅仅能“调度”事件。EventDispatcher实现了复杂的DOM事件模型,提供了关键的事件方法,通常会使用到的方法包括:

・ addEventListener方法:为EventDispatcher对象注册事件侦听器;

・ dispatchEvent方法:触发事件,也可以称为“调度事件”;

・ hasEventListener方法:检查对象是否为特定事件注册了事件侦听器;

・ removeEventListener:从EventDispatcher对象中删除事件侦听器。

注册事件侦听器

开发者可以通过两种方式注册事件侦听器:使用addEventListener方法和通过MXML标签设置。

1. 使用addEventListener方法

addEventListener方法的签名如下:

public function addEventListener (type:String, listener:Function, useCapture:

Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void

使用addEventListener方法,可以为EventDispatcher对象注册事件侦听器,以使侦听器能够接收事件通知。如我们之前所介绍的,可以为显示列表中任何节点对象注册事件侦听器,通过参数,可以为特定类型的事件注册侦听器,设置侦听器运行的事件阶段和优先级。

・ type:String:必需的参数,说明了侦听器所侦听的事件类型。事件类型可以是简单的字符串,也可以使用特定的事件对象常量。

・ listener:Function:必需的参数,也就是所谓的“侦听器”,负责在事件发生后响应事件。在Flex中,侦听器是一个接受Event对象作为唯一参数,并且不返回任何结果的函数,即:

function(evt:Event):void

在这一点上,Flex没有完全遵循W3C DOM Level 3事件规范。在该规范中,侦听器对象属于一个类的实例,而这个类实现了一个特殊的接口,名为“侦听器接口”。而在Flex中,把这个类“简化”为一个函数。

・ useCapture:Boolean:可选参数。说明侦听器是运行于捕获阶段、目标阶段还是冒泡阶段。useCapture设为true意味着侦听器只在捕获阶段处理事件。要在所有三个阶段都侦听事件,则须要分两次调用addEventListener:一次将useCapture设置为true,一次将useCapture设置为false,如我们在StartupSequence样例项目中所示。

・ priority:int:可选参数。设置事件侦听器的优先级,数字越大,优先级越高,优先级为n的侦听器会在优先级为n1的侦听器之前得到处理。如果两个或更多个侦听器共享相同的优先级,那么按照侦听器添加的顺序进行处理。默认优先级为0。如果希望修改侦听器的优先级,必须通过removeEventListener删除原有的事件侦听器,然后重新注册带有新的优先级参数的侦听器。

须要特别说明的是,事件侦听器的优先级保证了事件侦听器运行的顺序,但是,Flash Player并不会等高优先级的侦听器运行完毕后才去调用低优先级的侦听器。也就是说,低优先级侦听器的运行不能依赖于高优先级侦听器的处理,比如不能在低优先级侦听器运行时调用高优先级侦听器的处理结果。

2. 通过MXML标签设置事件侦听器:

使用MXML标签,也可以利用对象的事件属性来设置事件侦听器,如下所示,eventName为对象的事件属性,而其值可以直接为处理该事件的ActionScript代码段,或者ActionScript函数。

<mx:TagName eventName="[ActionScript代码段或事件侦听器函数]" />

例如,代码6-10中当用户点击按钮时,将会更新标签显示为“红色”。

代码6-10:使用MXML标签设置事件侦听器样例――内置ActionScript代码段

<mx:Button label=”控制按钮” click=”lblLight.text='红色'”/>

<mx:Label id="lblLight" text=”关闭”/>

对于复杂的事件侦听器,当然无法通过在标签中内置代码段实现。此时我们可以设置事件属性值为ActionScript函数。

例如,上述代码可以修改为如下方式,如代码6-11所示。

代码6-11: 使用MXML标签设置事件侦听器样例――ActionScript函数

<mx:Script>

<![CDATA[

private function myEventHandler():void{

lblLight.text="红色";

}

]]>

</mx:Script>

<mx:Button label="控制按钮" click="myEventHandler()"/>

<mx:Label id="lblLight" />

MXML标签注册事件侦听器看起来要比通过addEventListener方法容易得多,但是也同时带来了许多限制。MXML标签的方式远不如addEventListener方式灵活,使实现业务逻辑的ActionScript代码与展示外观的MXML代码过于紧密地耦合在一起。此外,MXML标签的方式也不能像addEventListener那样改变侦听事件的属性,如设置侦听器优先级等。

触发事件:dispatchEvent

所谓触发事件,就是通知Flash Player把事件对象调度到从显示列表根节点开始的事件流中。

dispatchEvent方法的签名如下:

public function dispatchEvent(event:Event):Boolean

在本章之前的代码样例中,你并不能看到dispatchEvent的身影。因为事件都由Flex自动触发了。然而,开发者有时须要“手工”触发事件,尤其在处理自定义事件时。我们会在本章余下章节看到如何使用dispatchEvent方法。

关于EventDispatcher更详细的信息,请参考“ActionScript 3.0语言参考”。我们在本章的6.5.1节“使用Action Script创建自定义事件”(见本页)将会再次看到EventDispatcher类。

6.4.3 使用内置事件的基本步骤

至此为止,我们讨论了Flex事件的基本概念:事件对象和事件流,初步了解了EventDispatcher类。回顾本章开始的信号灯应用可以看到,开发者要使用Flex内置事件,须要完成两个步骤:

1. 注册事件侦听器:如前文所述,可以通过addEventListener或MXML标签实现;

2. 实现侦听器函数:侦听器函数接收了事件对象,由此获知事件的相关信息,并响应事件。

使用ActionScript创建自定义事件

自定义事件只是一个“特别”的ActionScript类。开发者创建自定义事件无外乎完成如下几个任务:继承flash.events.Event、定义事件属性、编写类构造器、重载clone方法。容我一一道来。

继承flash.events.Event

如同Flex内置的事件,比如MouseEvent,自定义事件继承于flash.events.Event类。但事实上,你可以扩展其他事件类来创建自己的自定义事件,比如扩展MouseEvent。使用ActionScript创建事件的代码如下:

package events{

import flash.events.Event;

public class CustomEventClass extends Event{

}

}

定义属性

从某种程度看,事件就是系统传递的“消息”。Flash Player利用事件对象从事件目标向事件侦听器传递数据。flash.events.Event提供了“消息”所应有的基本信息,比如事件类型event.type等。然而,开发者通常希望“消息”能够携带更多的信息,提供更多的数据。在自定义事件中,通过定义属性,可以让事件携带更多的信息。

public var custEvProperty:String;

编写构造器

类当然离不开构造器。事件类的构造器要完成两项任务。

1. 调用Super()

通过Super()调用父类的构造器,以初始化从父类继承的属性等。通常情况下,子类构造器应该首先调用Super()方法。当然,如果没有为子类编写构造器(不添加构造器方法),编译器会自动添加一个构造器,并且也会调用Super()。但是,我们仍然推荐编写构造器,并且显式地调用Super()方法。

2. 设置属性

事件类型是最常用到的事件属性。Super()可以接受String类型的参数,由此设置父类事件中继承来的事件类型属性(event.type)。

除了事件类型外,事件的其他自定义属性可以作为构造器的参数传入,在构造器中完成初始化。更灵活的是,这些属性类型不仅仅局限于String、Number等基本类型,还可以是任何自定义类。这样,自定义事件就成为真正的“运输大队”,可以携带复杂的数据,成为更称职的“信使”。

通常的事件类构造器如下:

public function CustomEventClass(type:String,custEvPropertyParameter:String){

super(type)

this.custEvProperty=custEvPropertyParameter;

}

重载clone方法

创建自定义事件的最后一步是重载父类的clone方法,返回新的Event对象。当触发事件时,即dispatchEvent(event)时,EventDispatcher会自动调用clone方法获取新的Event对象。

重载clone方法将复制自定义类的所有属性。如果你没有对自定义事件类中添加的所有属性进行赋值的话,那么当侦听器处理触发的自定义事件时,就不会获得正确的属性值。

override public function clone():Event {

return new CustomEventClass(type,custEvProperty);

}

6.5.2 使用元数据[Event]定义事件

上一节,我们创建了自定义事件,那么如何使用自定义事件呢?还记得我们说过可以使用MXML标签注册事件侦听器吗?在下面代码中,click是Button组件的事件,我们只须为该事件设置侦听器方法或ActionScript处理代码。

<mx:Button label=”控制按钮” click=”lblLight.text='红色'”/>

组件能够获知有哪些内置事件可用,但是,如何让组件“认识”我们自定义的事件呢?

通过[Event]元数据,开发者可以为组件定义事件。编译器能够把这些自定义的事件识别为MXML标签属性。使用[Event]既可以为ActionScript组件定义事件,也可以为MXML组件定义事件,如图6-6所示。

[Event]元数据的签名如下:

Event(name="eventName",type="package.eventType")]

name说明了事件的名称,而type表明了该名称对应的事件类型。事件侦听器使用name进行注册。

为ActionScript组件定义事件

[Event]元数据必须置于包(package)定义之内,类(class)定义之上。如下:

package events{

[Event(name="sampleEvent", type="myEvents.SampleEvent")]

public class MyComponent extends UIComponent{

}

}

为MXML组件定义事件

在下面的例子中,我们为自定义组件LightConsole(组件为LightConsole.mxml,位于views目录下)定义了事件switchLightEvent,并在用户点击按钮时触发该事件。在CustomTraficLight.mxml中使用该组件时,编译器会把switchLightEvent识别为LightConsole的事件属性。在本章最后一个代码范例CustomTraficLight中,我们可以看到更全面的介绍。

图6-6 元数据[Event]定义事件

6.5.3 触发事件

我们使用dispatchEvent()方法触发事件。就像已经谈到的,由于我们的自定义组件继承自(或间接继承自)EventDispatcher类,因此获得了触发事件的能力。dispatchEvent接受Event事件对象作为参数,也意味着在触发事件前,我们要创建事件对象的实例,而dispatchEvent方法会把该事件对象调度到事件流中。

public dispatchEvent(event:Event):Boolean

回顾上一节的图6-6,可以看到,在LightConsole.mxml中我们通过下面的代码创建了SwitchLightEvent事件对象的实例,然后通过dispatchEvent方法触发了该事件。

var evtObj:SwitchLightEvent = new

SwitchLightEvent("switchLightEvent“,varSelectedLight);

dispatchEvent(evtObj);

6.5.4 创建事件侦听器

通过dispatchEvent方法触发事件后,Flash Player会在事件流中检查显示列表中的每个节点对象是否注册了事件侦听器。事件侦听器最终将完成针对事件的响应处理。依然回到图6-6,其中,我们通过创建事件侦听器方法switchEventHandler(),并通过赋予事件属性switchLightEvent值的方式注册了这个侦听器。事件侦听器方法switchEventHandler接受event事件对象为参数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值