用于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.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;
- }