论坛首页 编程语言技术论坛

改进ActionScript3的事件机制:事件桥EventBridge

浏览 3007 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-02-13   最后修改:2009-03-25
     告示:本文为原创文章, 如果转载请注明出处!http://summerofthatyear-gmail-com.iteye.com/blog/328259
      在Flex应用中,由于actionscript3的事件机制是在显示对象一层层向上冒泡的,所以如果在比较复杂的页面结构的时候,你可能会被事件的一层层的冒泡搞的晕头转向.而且在底层派发事件,高层侦听事件,也是很麻烦的一件事情.
      有了"事件桥"这一切将不再是问题,事件桥的功能是它可以把一个事件从一个地方传到任意另外一个地方.不需要冒泡!因为他不通过显示对象的父子关系级级散发,而通过一个第三方类来跳转。这样即提高了性能又方便了用户。
      听不懂没关系, 举个例子就一目了然了.
      这个例子很简单, 是一个选择用户的模块, 就是一个TextArea和一个Button, 点击Button弹出一个TitleWindow(PopUpManager). TitleWindow有一个DataGrid, 然后在DataGrid里面选择一个用户返回;
      首先是一个用户对象:
package com.montage.vo
{
	/**
	 * @author Montage
	 */	
	public class User
	{
		public function User()
		{
		}
		
		public var name:String;
		public var country:String;

	}
}


选择完了用户, 所需要的事件
package com.montage.events
{
	import com.montage.vo.User;
	
	import flash.events.Event;

	/**
	 * @author Montage
	 */	
	public class UserEvent extends Event
	{
		public static var SELECTED_USER:String = "selectedUser";
		
		public var user:User;
		
		public function UserEvent(type:String,
								  bubbles:Boolean=false, 
								  cancelable:Boolean=false)
		{
			super(type, bubbles, cancelable);
		}
	}
}



下面就是“事件桥”,他似乎没有什么代码,就是一个单件类的架子,但是可别小看了它,由于它继承了EventDispatcher所以它可以做到听/发事件!
package com.montage.model
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	//////////////////////
	//
	// events
	//
	//////////////////////
	/**
	 * 给当前类注册一个事件
	 */	
	[Event(name="selectedUser", type="com.montage.events.UserEvent")]

	/**
	 * 
	 * @author Montage 
	 */	
	public class EventBridge extends EventDispatcher
	{
		
		private static var instance:EventMessage = null;
		
		public function EventMessage()
		{
			if( instance != null )
			{
				throw new Error("EventBridge是一个单件类,只能被实例化一次!");
			}
		}
		
		public static function getInstance():EventBridge
		{
			if( instance == null )
			{
				instance = new EventBridge();
			}
			return instance;
		}
	}
}


以下是用户列表界面UserList.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="400" height="300" title="选择用户">
	<mx:Script>
		<![CDATA[
			import mx.controls.Alert;
			import com.montage.events.UserEvent;
			import com.montage.vo.User;
			import com.montage.model.EventMessage;
			import mx.managers.PopUpManager;
			
			private var eventBridge:EventBridge = EventBridge.getInstance();
			
			private function submitHandler():void
			{
				if( grid.selectedIndex > -1 )
				{
					var item:XML = XML( grid.selectedItem );
					
					//创建一个用户
					var user:User = new User();
					user.name = item.@name;
					user.country = item.@country;
					
					//创建一个UserEvent事件, 把刚刚创建好的user赋给它
					var event:UserEvent = new UserEvent( UserEvent.SELECTED_USER );
					event.user = user;
					
					//用EventBridge将这个事件发送出去
					eventBridge.dispatch( event );
					cancelHandler();
				}
				else
				{
					Alert.show("请选择一个用户!");
				}
			}
			
			private function cancelHandler():void
			{
				PopUpManager.removePopUp( this );
			}
		]]>
	</mx:Script>
	<mx:XML id="users" source="user.xml"/>
	<mx:DataGrid id="grid" width="100%" height="100%" dataProvider="{users.User}">
		<mx:columns>
			<mx:DataGridColumn headerText="姓名" dataField="@name"/>
			<mx:DataGridColumn headerText="国家" dataField="@country"/>
		</mx:columns>
	</mx:DataGrid>
	<mx:ControlBar width="100%">
		<mx:Spacer width="100%"/>
		<mx:Button label="确定" click="submitHandler()"/>
		<mx:Button label="取消" click="cancelHandler()"/>
	</mx:ControlBar>
</mx:TitleWindow>


用户数据源user.xml
<root>
	<User name="David" country="America"/>
	<User name="Tome" country="Canada"/>
	<User name="Montage" country="China"/>
</root>


主界面:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="init()" fontSize="12">
	<mx:Script>
		<![CDATA[
			import com.montage.events.UserEvent;
			import com.montage.model.EventMessage;
			import mx.managers.PopUpManager;
			import com.montage.view.user.UserList;
			
			private var eventBridge:EventBridge= EventBridge.getInstance();
			
			private function init():void
			{
				eventBridge.addEventListener(UserEvent.SELECTED_USER, selectedUserHandler);
			}
			
			/**
			 * 选择好以后的反馈
			 */
			private function selectedUserHandler( event:UserEvent ):void
			{
				textArea.htmlText = "你选择了:<b>" + event.user.name + "</b>("+ event.user.country +")";
			}
			
			/**
			 * 弹出选择用户的窗口PopUpManager
			 */
			private function clickHandler():void
			{
				var userList:UserList = UserList( PopUpManager.createPopUp(this, UserList, true) );
				userList.x = ( width - userList.width ) / 2;
				userList.y = ( height - userList.height ) / 2;
			}
			
		]]>
	</mx:Script>
	<mx:Panel width="400" height="300" layout="vertical" paddingLeft="5" paddingRight="5" paddingTop="5">
		<mx:TextArea id="textArea" width="100%"/>
		<mx:Button label="选择用户" click="clickHandler()"/>
	</mx:Panel>
</mx:Application>
   发表时间:2009-02-25  
你的单件类肯定不是单件的。我要是用一直就用new EventMessage(),那我可以创建无数个实例。。。
0 请登录后投票
   发表时间:2009-02-28  
浮尘过往 写道

你的单件类肯定不是单件的。我要是用一直就用new EventMessage(),那我可以创建无数个实例。。。


#         public function EventMessage() 
#         { 
#             if( instance != null ) 
#             { 
#                 throw new Error("EventMessage是一个单件类,只能被实例化一次!"); 
#             } 
#         } 
#          
#         public static function getInstance():EventMessage 
#         { 
#             if( instance == null ) 
#             { 
#                 instance = new EventMessage(); 
#             } 
#             return instance; 
#         } 

上面写的很清楚了 如果实例已经存在 是会报错的
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics