`
kv0002
  • 浏览: 8499 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Flex对象与组件的数据动态双向绑定

阅读更多
用于Flex中Entity对象与Display对象之间的数据双向动态绑定,支持TextInput、DateField、ComboBox。

package controller.utils{
	import com.ericfeminella.collections.HashMap;
	import com.ericfeminella.collections.IMap;
	
	import flash.display.DisplayObject;
	import flash.utils.describeType;
	
	import mx.binding.utils.BindingUtils;
	import mx.binding.utils.ChangeWatcher;
	import mx.events.PropertyChangeEvent;
	import mx.utils.ObjectProxy;
	
	/**
	 * @Description: BindingHelper
	 * @author Lyon
	 */
	public class BindingHelper{
		/**
		 * 目前支持的绑定组件类型 
		 */		
		private static const typeMap: Object = {	'mx.controls::TextInput' : 'text',
																		'mx.controls::DateField' : 'selectedDate',
																		'mx.controls::ComboBox': 'selectedItem'
																		};		
		/**
		 * 存储监控对象的句柄
		 * key: entityObj
		 * value: ChangeWatcher
		 */		
		private static var handleList:IMap = new HashMap();
		
		/**  
         * 对象与组件的数据动态双向绑定  
         * @param entityObj   Entity Object
         * @param displayObj  MX控件
         * @param type       	 	控件类型,如:'mx.controls::TextInput'
         * @exclude					需要排除的property
         * @bidirectional      		是否做双向绑定(如果为false,那么只做entity到displayObject的绑定)
         * @param commitOnly
         */	
		public static function bidirectionalDataBind(
									entityObj:Object, 
									displayObj:DisplayObject,
									exclude:Array=null,
									bidirectional:Boolean=true,
									type:String='ALL',									
									commitOnly:Boolean = false):void{
			if(type == 'ALL'){
				for (var typeTmp:String in typeMap){
					bidirectionalDataBind(entityObj,displayObj,exclude,bidirectional,typeTmp,commitOnly);
				}
			}else{
				//通过反射机制取出当前MXML中的信息
				var instanceInfo:XML=flash.utils.describeType(displayObj);
				var properties:XMLList =instanceInfo..accessor.(@type==type);
				var tmpObj:ObjectProxy;
	//			trace(instanceInfo..accessor.(@type==type));
	
				var prop:String = BindingHelper.getSiteProp(type);
	
				for each(var propertyInfo:XML in properties){
					//此处取出的为textinput的id
				  	var proName:String = propertyInfo.@name;
				  	
				  	// 需要排除的property
				  	if(exclude != null && exclude.indexOf(proName) != -1){
				  		continue;
				  	}
				  	
				  	// 检查该property是否存在
				  	if(BeanUtils.checkPropertyExist(entityObj,proName) == false){
				  		continue;
				  	}
				  	
				  	try{
					  	// ComboBox
					  	if(type == 'mx.controls::ComboBox'){
					  		if(handleList.getValue(entityObj) == null){
					  			handleList.put(entityObj,new HandleObject(entityObj));
					  		}
					  		
							var cw:ChangeWatcher = ChangeWatcher.watch(entityObj,proName,setData);
							HandleObject(handleList.getValue(entityObj)).addChangeWatcher(proName,cw);
							
							BindingUtils.bindProperty(entityObj,proName,DisplayObject(displayObj[proName]),prop,commitOnly);
					  	}else{
					  		BindingUtils.bindProperty(DisplayObject(displayObj[proName]),prop,entityObj,proName,commitOnly);
							if(bidirectional == true)
								BindingUtils.bindProperty(entityObj,proName,DisplayObject(displayObj[proName]),prop,commitOnly);
					  	}
					 }catch(err:Error){
				  		trace(err.message);
				  	}
				}
			}
		}
		
		/** 
		 * 清空监控对象的句柄集合
		 */		
		public static function clean():void{
			if(handleList != null){
				for each(var ho:Object in handleList.getValues()){
					HandleObject(ho).clean();
				}
				
				handleList.clear();
			}
		}
		
		/**
		 * 监听ComboBox事件的变化
		 * @param obj
		 */
		private static function setData(obj:PropertyChangeEvent):void{
			if(obj.newValue == null){
				return;
			}
			var ho:HandleObject = handleList.getValue(obj.source);			
			var cw:ChangeWatcher = ho.getChangeWatcher(obj.property);
			
			if(obj.newValue is String){
				cw.unwatch();
				cw = ChangeWatcher.watch(obj.source,obj.property,setData);
				ho.addChangeWatcher(obj.property,cw);
				return;
			}else{	
				var code:Object = obj.newValue.code;
				obj.source[obj.property] = code;
			}
		}
		
		/**
		 * 返回组件TYPE对应的需要填充的属性名称 
		 * @param type
		 * @return 
		 */		
		private static function getSiteProp(type: String): String{
			for (var name:String in typeMap){
				if(name == type){
					return typeMap[name];
				}
			}
			return null;
		}
	}
}

import mx.binding.utils.ChangeWatcher;
import com.ericfeminella.collections.IMap;
import com.ericfeminella.collections.HashMap;
internal class HandleObject{
		private var entityObject:*;
		private var properityList:IMap;
		
		public function HandleObject(entityObject:*):void{
			this.entityObject = entityObject;
			properityList = new HashMap();
		}
		
		public function addChangeWatcher(propName:Object, cw:ChangeWatcher):void{
			properityList.put(propName,cw);
		}
		
		public function getChangeWatcher(propName:Object):ChangeWatcher{
			return properityList.getValue(propName);
		}
		
		public function clean():void{
			for each(var cw:Object in properityList.getValues()){
				ChangeWatcher(cw).unwatch();
			}
			
			properityList.clear();
		}
	}

package controller.utils{
	
	import com.adobe.serialization.json.JSON;
	
	import mx.collections.ArrayCollection;
	import mx.utils.ObjectUtil;
	import mx.utils.StringUtil;

	/**
	 * @Description: Object Utils
	 * @author Lyon
	 */
	public class BeanUtils{		
		/**
		 * 检查对象的property是否存在
		 * @param obj
		 * @param proName
		 * @return 
		 */		
		public static function checkPropertyExist(targetObj:*, proName:String):Boolean{
			if(targetObj as String 
					|| targetObj as int
					|| targetObj as Date
					|| targetObj as Number){
				return false;
			}
			
			var objInfo:Object = ObjectUtil.getClassInfo(targetObj);
			for each(var name:String in objInfo.properties){
				if(name == proName){
					return true;
				}
			}
			
			return false;
		}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics