我们可以通过"信号灯应用"初步了解Flex的事件模型。这个简单的例子包含了两个事件:creationComplete和MouseEvent.CLICK。
讨论MouseEvent.CLICK
这里没有什么高科技,只是某人点击了按钮,然后应用做出响应,更新了标签的显示信息。
从程序员的视角看,这个过程涉及了三个主要元素,也正是事件的三个要素:
事件源:事件源指的是发生事件的对象。本例中即三个按钮;
侦听器:侦听器是一个具体的方法,负责处理事件响应。侦听器要被注册到某个可以接收到事件通知的对象上。本例中,侦听器是myEventHandler方法,被注册到按钮的容器ctnButtons对象上;
事件:事件本身就是一个对象。侦听器在处理事件的时候,有时候需要知道事件的来龙去脉,比如事件源是谁?发生了什么事情?事件对象封装了这些信息。本例中,侦听器myEventHandler方法的参数即事件对象。
从Flex程序编写的角度看,全过程如下:
首先放置了"事件源":三个按钮btnGreen、btnRed、btnBlue。三个按钮被置于一个容器ctnButtons中。
创建事件侦听器myEventHandler方法。侦听器根据事件对象内封装的信息,决定如何响应事件。这里的情况有一点复杂,侦听器myEventHandler还须要解决两个问题。
1. 用户点击的不是按钮怎么办?
在注册事件侦听器的时候,我们只告诉Flash Player在发生MouseEvent.CLICK事件时调用myEventHandler。这就意味着,用户点击任何容器中的对象,都会触发该事件。举个例子来说,如果容器中除了按钮外,还包含了一个文本输入框组件,用户点击了该组件,会发生什么?FlashPlayer会即刻调用侦听器myEventHandler,但是我们的侦听器很聪明,他会检测事件源是否为"按钮",如果不是按钮,那么什么都不会发生。秘诀在于传递给myEventHandler的Event类型参数:event。Event是在事件发生时,由Flash Player隐式创建的,因此你看不到该对象的声明和创建代码。Event描述了所发生的事件,这里event.target告诉myEventHandler事件源是谁。
代码event.target is Button检查事件源是否为按钮对象。
2. 用户按了哪个按钮?
在我们的例子中,myEventHandler知道用户点击了哪个按钮,继而相应地更新lblLightInfo标签信息。这同样是通过事件对象来实现的。Event对象实例event通过event.target告诉了myEventHandler谁是事件源,继而通过强制类型转换Button(event.target),得到了发生事件源按钮对象,从而获取了它的label属性。
之后,addEventListener方法把"事件侦听器"myEventHandler注册在容器ctnButtons上:
MouseEvent.CLICK事件发生之后(民间说法即:有人点击了按钮),Flash Player立即向"全世界"广播该事件消息。当发现容器ctnButtons注册了针对MouseEvent.CLICK事件的侦听器myEventHandler时,就调用该方法,并把事件对象发送过去。
讨论creationComplete
与MouseEvent.CLICK事件不同,事件creationComplete并不是由用户的操作触发的。当信号灯应用初始化完毕,Flash Player就会自动触发该事件。
有意思的是,在这里我们并没有看到像MouseEvent.CLICK事件那样,通过addEventListener注册creationComplete事件的侦听器,那么,Flash Player如何知道谁来处理该事件呢?实际上,我们仍然为该事件注册了事件侦听器initApp()。只不过使用了另外一种方式:在MXML标签中定义事件侦听器:<mx:Application … creationComplete="initApp()">。在事件发生后,Flash Player会自动调用initApp()方法。



