Flex事件机制(三)

上一篇主要以代码的方式说明了如何使用自定义事件在父子组件之间传递数据,那么在开发中,我们可能会遇到另一种情况,就是想在任意一个地方监听到任意一个组件中被触发的事件,这样事件处理更灵活,并不局限于父子组件之间,那么下面就说明这种情况如何处理。

       Flex中所有的组件都间接继承自EventDispatcher,通过查看Flex API,了解一下这个类中的方法。       

       如图所见,该类包含了派发事件、监听事件、移出事件等方法,那么通过这个类就可以实现本文开篇所提出的那种情况,分析一下,监听事件的对象和派发事件的对象必须是同一个对象,这样事件才能被捕获,所以我们需要写一个单例的类,并且组合EventDispatcher,可以满足需求。

       events/MyEventDispatcher.as,这里同样不建议以My起头命名,只是测试用。

package events
{
	import events.MyEvent;	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;	
	import mx.core.Singleton;
	public class MyEventDispatcher
	{
		private static var _inst:MyEventDispatcher;
		private var eventDispatcher:IEventDispatcher;
		public function MyEventDispatcher(singleton:Singleton)
		{
			if(singleton == null)
			{
				throw new Error("Create MyEventDispatcher Error!");
			}
			eventDispatcher = new EventDispatcher();
		}
		public static function getInstance():MyEventDispatcher
		{
			if (!_inst)
			{
				_inst = new MyEventDispatcher(new Singleton);
			}
			return _inst;
		}
		public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, pririty:int=0, useWeakReference:Boolean=true):void
		{
			eventDispatcher.addEventListener(type, listener, useCapture, pririty, useWeakReference);
		}
		public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=true):void
		{
			eventDispatcher.removeEventListener(type, listener, useCapture);
		}
		public function dispatchEvent(event:MyEvent):Boolean
		{
			return eventDispatcher.dispatchEvent(event);
		}
		public function hasEventListener(type:String):Boolean
		{
			return eventDispatcher.hasEventListener(type);
		}
		public function willTrigger(type:String):Boolean
		{
			return eventDispatcher.willTrigger(type);
		}
	}
}
class Singleton {}

       为了节省空间,类里不加注释了,其实也不要紧,功能很简单,组合了EventDispatcher对象,对其做了一层代理,并且对MyEventDispatcher单例话,为什么采用单例上面已经说过了,但是为什么使用组合而不是继承呢,在OOPS(面向对象程序设计系统)中,有一条原则是优先使用组合而非继承,组合比继承更灵活,组合允许在运行期间通过设置类的属性来改变类的行为,并且可以使用接口来组合一个类,提供了更高的灵活性。

       到目前为止,我们的工作已经完成一大半了,在上一篇中设计了一个自定义事件类,也就是events/MyEvent.as,我们可以在该类中加入一个dispatch方法,创建完事件之后可以派发,代码如下:       

/**
 * 派发事件
 * @return 
 */
public function dispatch():Boolean
{
  return MyEventDispatcher.getInstance().dispatchEvent(this);
}

       这样,创建完自定义事件之后,就可以直接派发事件了,那么使用起来就很方便了,下面是具体使用代码,一个应用中有两个自定义组件,组件一中有个TextArea,组件二中有个按钮,点击按钮,将数据传递到TextArea中。

       EventTest.mxml

<?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="components.*">
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
	<components:component1 />
	<components:component2 />
</s:Application>

       components/component1.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
		 xmlns:s="library://ns.adobe.com/flex/spark" 
		 xmlns:mx="library://ns.adobe.com/flex/mx"
		 creationComplete="creationCompleteHandler(event)">
	<fx:Script>
		<![CDATA[
			import events.MyEventDispatcher;
			import events.MyEvent;
			import mx.events.FlexEvent;			
			protected function creationCompleteHandler(event:FlexEvent):void
			{
				MyEventDispatcher.getInstance().addEventListener(MyEvent.SHOWINFO, showInfo);
			}			
			protected function showInfo(event:MyEvent):void
			{
				textArea.text = event.data;
			}			
		]]>
	</fx:Script>
	<s:TextArea id="textArea" />
</s:Group>

       components/component2.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
		 xmlns:s="library://ns.adobe.com/flex/spark" 
		 xmlns:mx="library://ns.adobe.com/flex/mx">	
	<fx:Script>
		<![CDATA[
			import events.MyEvent;
			import events.MyEventDispatcher;
			protected function buttonClickHandler(event:MouseEvent):void
			{
				var myEvent:MyEvent = new MyEvent(MyEvent.SHOWINFO);
				myEvent.data = "哈哈";
				myEvent.dispatch();
			}
		]]>
	</fx:Script>
	<s:Button label="显示内容" click="buttonClickHandler(event)"/>
</s:Group>

       好,这样就实现了在任意一个地方监听到任意一个组件中被触发的事件的功能,文中如有错误之处,欢迎指出,大家共同进步。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Flutter入门

Flutter入门三部曲(2) - 界面开发基础

上一节我们熟悉了初始化后的flutter的界面。这一节,我们就来重点了解一下这部分的内容。

2822
来自专栏前端架构与工程

【翻译】JavaScript内存泄露

我们在进行JavaScript开发时,很少会考虑内存的管理。JavaScript中变量的声明和使用看起来是一件很轻松的事,底层的细节处理交给浏览器去做就好了。 ...

2356
来自专栏macOS 开发学习

Swift 日常使用Tip

Swift中的Struct都有个系统提供默认的包含所有成员遍量的init方法,如果我们添加自定义的init方法时,系统默认提供的就会消失,如果需要既可以保留系统...

763
来自专栏后台及大数据开发

MongoDB基本命令用

成功启动MongoDB后,再打开一个命令行窗口输入mongo,就可以进行数据库的一些操作。

521
来自专栏与神兽党一起成长

怎么在elementary OS中使用中文输入法

能找到官网或官网论坛的帖子,那么就是解决问题的一半了。刚好我也搜到了这个帖子, http://elementary.io/answers/how-to-type...

2021
来自专栏Flutter入门

Vue 绑定简单分析实现

使用js es6 中 Object.defineProperty为我们自己定义的VM创建示例。同时这个方法通过提供了set.get方法的触发我们的监听事件。

941
来自专栏菩提树下的杨过

Javascript版的Repeater控件实现

其实有点标题党了,呵呵,主要是项目的特殊性,出于性能考虑项目经理规定不能用任何服务端控件(包括Repeater控件),同时尽量减少服务端处理,并尽可能压缩最终生...

2085
来自专栏Flutter入门

Flutter入门三部曲(2) - 界面开发基础

上一节我们熟悉了初始化后的flutter的界面。这一节,我们就来重点了解一下这部分的内容。

2710
来自专栏CSDN技术头条

深入讲解 Vue 中实现原理

随着 Vue2.0 的发布,前端入门的要求也越来越低,已至于 Vue 已经成为一个前端的标配,最近也面了很多前端开发工程师,发现大部分都停留在用的阶段上,建议大...

1032
来自专栏大内老A

一句代码实现批量数据绑定[下篇]

《上篇》主要介绍如何通过DataBinder实现批量的数据绑定,以及如何解决常见的数据绑定问题,比如数据的格式化。接下来,我们主要来谈谈DataBinder的设...

2095

扫码关注云+社区