CG橙子精彩导航: CG橙子搜索引擎 | 博客 | 动画视频
广告|项目|培训|竞价排名  
86CG > CG教程 > 平面 > Flash > 组件事件模型part1-事件分派器(eventDispatcher)

组件事件模型part1-事件分派器(eventDispatcher)

类型:翻译 | 来自:86CG | 时间:2007-1-22 |  点击:
V2组件的事件模型是基于监听器(listener),而不是像V1中基于回调函数(callbacks)。

在Flash MX的V1组件中,比如你可以使用”setClickHandler”将一个函数注册(register):为当组件被点击的时候调用的回调函数。你需要指定包含着个函数的对象,如果你没有指定,Flash会自动在组件的_parent范围内查找这个函数。但这种方法有一些小的局限,因为你必须有让事件触发时调用的一段代码,并且给所有的相应的目标发送这个消息。

Flash MX实际上有一个内建机制用于实现事件监听,就是ASBroadcaster。这是一个允许你快速建立一个事件广播模型的内部对象(mm的帮助文档并没有提到),提供了添加、移除监听对象,并对这些对象广播事件的方法。但被发现存在一些小bug,导致”only every second eventhandler being called, if listeners are removed in the eventhandler”(不是很理解,汗!)。其他也还有另外一些用于克服这个缺点的基于监听器的事件模型。

Flashplayer7仍然支持ASBroadcaster,在将影片导出为Flashplayer7版本的swf时,似乎也修正了这个bug。但注意在Flash MX 2004是AsBroadcaster,这里s小写!

上面扯了这么多目的是引出下面这些——

V2组件实现了一个不用到AsBroadcaster的监听器模型。就是EventDispatcher类(位置在安装文件夹\en\First Run\Classes\mx\events下),用于给UIObject(是所有组件的基础)添加事件广播(在2004中称为”分派(dispatch)”)功能。它与AsBroadcaster的工作方式在本质上是相同的。

1) 通过调用EventDispatcher.initialize(dispathingObj)建立一个分派器对象。

2) 调用dispatchingObj.addEventListener(“event”,listeringObj)和

dispatchingObj.removeEventListener(listeningObj)来添加、移除一个监听器。

3) 调用dispatchingObj.dispatchEvent(eventObj)为这些监听器分派(广播)事件。

有一些细节需要注意:

1) 看起来似乎EventDispatcher基于被注册监听的事件的类型将监听器加以分类。而据我所知Asbroadcaster仅仅将所有的监听器依附于一个监听器组,并为所有监听器广播所有事件——如果一个监听器没有设置特定的事件处理方法则默认事件广播失败。EventDispatcher实际上为每个事件创建了各自的监听器组。这样,当一个特定的事件被分派时,仅仅查找此事件相关的监听器组。这是一个细节的,也是一个重大的差别!

2) 当通过EventDispatcher分派事件时,仅仅传递了一个包含所有你想要传递给监听器内容的属性的”事件对象(event object)”而不是像之前一样需要传递此事件与一大堆的参数。这个对象的一些重要属性有:

“type”-必需的属性,指明你分派的事件。

“target”-可选的属性,允许你向监听器的处理函数中传递一个对象的引用。如果未指明,则默认指向你的分派器对象。

3) 在你的dispatcher传递被事件监听器调用的该事件之前,实际上会先调用一个内部的方法(有些像V1组件中的”click handler”),这让你如果需要可以使dispatcher对它本身做一些处理(所以类似V1组件中的回调模型)。使用这个功能,你需要在你的分派器对象中定义一个以[事件名+”Handler”]命名的方法,比如如果有一个click事件,则应定义为”clickHandler”。它将传递2)中提到的事件对象。

4) dispatcher可以接受Object、MovieClip或者单纯的函数(function)作为监听器。当你使用它们作为监听器的时候,还是会有稍许的差别:

如果使用Object、MovieClip建立监听器,则有两种方法来捕获事件:

a) 在Object或者MovieClip上定义一个与所监听的事件同名的方法。例如,监听click事件,则应建立myObj.click=function(eventObj){//…};

b) 在Object或者MovieClip上定义一个”handlerEvent(eventObj)”。它将成为一个类的接口(interface),通过它你的监听器可以处理相应被分派的事件(event dispatches)。所有被分派的事件都会传出这个方法,也就意味着你必须察看eventObj.type才能知道具体是哪个事件被触发并且执行相应的代码。

那么在使用组件时具体应该如何做呢?这里给出一个简单的例子。假设场景中有一个Button组件,名为”submitBtn”,你应该这样做以建立一个监听器对象:

// Listening object contains a function with the same name as
// the dispatched event
var listeningObj:Object = new Object();
listeningObj.click = function(eventObj:Object):Void {
trace("submitted by " + eventObj.target);
}
submitBtn.addEventListener("click",listeningObj);
或者这样:

// Use a central "handleEvent" function to mitigate all events
var listeningObj:Object = new Object();
listeningObj.handleEvent = function(eventObj:Object):Void {
if (eventObj.type == "click") {
trace("submitted by " + eventObj.target);
}
}
submitBtn.addEventListener("click",listeningObj);
或者像V1组件中一样:
// Old school click handler style
submitBtn.clickHandler = function():Void {
trace("submitted by " + this);
}

另外,使用一个普通的函数作为监听器。假设你想要从不同的分派对象监听相同的事件,如果已经建立了包含click方法的监听对象,那么要区分具体是哪个dispatcher分派的事件的唯一的办法就是察看传递的eventObj的target属性。但如果你定义一系列函数作为监听器,你就可以为任何被分派的事件指定具体如何执行。

// Use plain functions as listeners and specify which one
// you want to listen for any given event from any given
// dispatcher
function handleSubmit = function(eventObj:Object):Void {
trace("submitted!");
}
function handleReset = function(eventObj:Object):Void {
trace("reset!");
}
submitBtn.addEventListener("click",handleSubmit);
resetBtn.addEventListener("click",handleReset);
当然你也可以通过为每个dispatcher建立一个对象完成相同的任务。

 
(完)
可打印版本 | 文章评论 | 我来纠错

|网友评论

    笔名:

    内容:

        

    iPad售楼系统软件

    国内最好的全景漫游软件任我游

    iHouse售楼系统软件

    谁都可以轻松开发APP(HTML5APP)

    全景视频3D视频视景360

    HTML5移动平台iOS/Android解决方案

    强大的地图引擎ZoomMap

    环物浏览器Object360

    |热点关注

    关于我们 - 版权隐私 - 友情链接 - 广告服务 - 项目合作 - 网站地图 - 联系方式

    ©Copyright by 86CG.COM, 2006-2013. All rights reserved 京ICP备06059503号