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

用于Flex中Entity对象与Display对象之间的数据双向动态绑定,支持TextInput、DateField、ComboBox。
  1 package controller.utils{
  2     import com.ericfeminella.collections.HashMap;
  3     import com.ericfeminella.collections.IMap;
  4     
  5     import flash.display.DisplayObject;
  6     import flash.utils.describeType;
  7     
  8     import mx.binding.utils.BindingUtils;
  9     import mx.binding.utils.ChangeWatcher;
 10     import mx.events.PropertyChangeEvent;
 11     import mx.utils.ObjectProxy;
 12     
 13     /**
 14      * @Description: BindingHelper
 15      * @author Lyon
 16      */
 17     public class BindingHelper{
 18         /**
 19          *  目前支持的绑定组件类型 
 20          */        
 21         private static const typeMap: Object = {    'mx.controls::TextInput' : 'text',
 22                                                                         'mx.controls::DateField' : 'selectedDate',
 23                                                                         'mx.controls::ComboBox''selectedItem'
 24                                                                         };        
 25         /**
 26          *  存储监控对象的句柄
 27          * key: entityObj
 28          * value: ChangeWatcher
 29          */        
 30         private static var handleList:IMap = new HashMap();
 31         
 32         /**  
 33          *  对象与组件的数据动态双向绑定  
 34          * @param entityObj   Entity Object
 35          * @param displayObj  MX控件
 36          * @param type                 控件类型,如:'mx.controls::TextInput'
 37          * @exclude                     需要排除的property
 38          * @bidirectional               是否做双向绑定(如果为false,那么只做entity到displayObject的绑定)
 39          * @param commitOnly
 40          */    
 41         public static function bidirectionalDataBind(
 42                                     entityObj:Object, 
 43                                     displayObj:DisplayObject,
 44                                     exclude:Array=null,
 45                                     bidirectional:Boolean=true,
 46                                     type:String='ALL',                                    
 47                                     commitOnly:Boolean = false):void{
 48             if(type == 'ALL'){
 49                 for (var typeTmp:String in typeMap){
 50                     bidirectionalDataBind(entityObj,displayObj,exclude,bidirectional,typeTmp,commitOnly);
 51                 }
 52             }else{
 53                 //通过反射机制取出当前MXML中的信息
 54                 var instanceInfo:XML=flash.utils.describeType(displayObj);
 55                 var properties:XMLList =instanceInfo..accessor.(@type==type);
 56                 var tmpObj:ObjectProxy;
 57     //            trace(instanceInfo..accessor.(@type==type));
 58     
 59                 var prop:String = BindingHelper.getSiteProp(type);
 60     
 61                 for each(var propertyInfo:XML in properties){
 62                     //此处取出的为textinput的id
 63                       var proName:String = propertyInfo.@name;
 64                       
 65                       // 需要排除的property
 66                       if(exclude != null && exclude.indexOf(proName) != -1){
 67                           continue;
 68                       }
 69                       
 70                       // 检查该property是否存在
 71                       if(BeanUtils.checkPropertyExist(entityObj,proName) == false){
 72                           continue;
 73                       }
 74                       
 75                       try{
 76                           // ComboBox
 77                           if(type == 'mx.controls::ComboBox'){
 78                               if(handleList.getValue(entityObj) == null){
 79                                   handleList.put(entityObj,new HandleObject(entityObj));
 80                               }
 81                               
 82                             var cw:ChangeWatcher = ChangeWatcher.watch(entityObj,proName,setData);
 83                             HandleObject(handleList.getValue(entityObj)).addChangeWatcher(proName,cw);
 84                             
 85                             BindingUtils.bindProperty(entityObj,proName,DisplayObject(displayObj[proName]),prop,commitOnly);
 86                           }else{
 87                               BindingUtils.bindProperty(DisplayObject(displayObj[proName]),prop,entityObj,proName,commitOnly);
 88                             if(bidirectional == true)
 89                                 BindingUtils.bindProperty(entityObj,proName,DisplayObject(displayObj[proName]),prop,commitOnly);
 90                           }
 91                      }catch(err:Error){
 92                           trace(err.message);
 93                       }
 94                 }
 95             }
 96         }
 97         
 98         /** 
 99          *  清空监控对象的句柄集合
100          */        
101         public static function clean():void{
102             if(handleList != null){
103                 for each(var ho:Object in handleList.getValues()){
104                     HandleObject(ho).clean();
105                 }
106                 
107                 handleList.clear();
108             }
109         }
110         
111         /**
112          *  监听ComboBox事件的变化
113          * @param obj
114          */
115         private static function setData(obj:PropertyChangeEvent):void{
116             if(obj.newValue == null){
117                 return;
118             }
119             var ho:HandleObject = handleList.getValue(obj.source);            
120             var cw:ChangeWatcher = ho.getChangeWatcher(obj.property);
121             
122             if(obj.newValue is String){
123                 cw.unwatch();
124                 cw = ChangeWatcher.watch(obj.source,obj.property,setData);
125                 ho.addChangeWatcher(obj.property,cw);
126                 return;
127             }else{    
128                 var code:Object = obj.newValue.code;
129                 obj.source[obj.property] = code;
130             }
131         }
132         
133         /**
134          *  返回组件TYPE对应的需要填充的属性名称 
135          * @param type
136          * @return 
137          */        
138         private static function getSiteProp(type: String): String{
139             for (var name:String in typeMap){
140                 if(name == type){
141                     return typeMap[name];
142                 }
143             }
144             return null;
145         }
146     }
147 }
148 
149 import mx.binding.utils.ChangeWatcher;
150 import com.ericfeminella.collections.IMap;
151 import com.ericfeminella.collections.HashMap;
152 internal class HandleObject{
153         private var entityObject:*;
154         private var properityList:IMap;
155         
156         public function HandleObject(entityObject:*):void{
157             this.entityObject = entityObject;
158             properityList = new HashMap();
159         }
160         
161         public function addChangeWatcher(propName:Object, cw:ChangeWatcher):void{
162             properityList.put(propName,cw);
163         }
164         
165         public function getChangeWatcher(propName:Object):ChangeWatcher{
166             return properityList.getValue(propName);
167         }
168         
169         public function clean():void{
170             for each(var cw:Object in properityList.getValues()){
171                 ChangeWatcher(cw).unwatch();
172             }
173             
174             properityList.clear();
175         }
176     }
177 

 

 1 package controller.utils{
 2     
 3     import com.adobe.serialization.json.JSON;
 4     
 5     import mx.collections.ArrayCollection;
 6     import mx.utils.ObjectUtil;
 7     import mx.utils.StringUtil;
 8 
 9     /**
10      * @Description: Object Utils
11      * @author Lyon
12      */
13     public class BeanUtils{        
14         /**
15          *  检查对象的property是否存在
16          * @param obj
17          * @param proName
18          * @return 
19          */        
20         public static function checkPropertyExist(targetObj:*, proName:String):Boolean{
21             if(targetObj as String 
22                     || targetObj as int
23                     || targetObj as Date
24                     || targetObj as Number){
25                 return false;
26             }
27             
28             var objInfo:Object = ObjectUtil.getClassInfo(targetObj);
29             for each(var name:String in objInfo.properties){
30                 if(name == proName){
31                     return true;
32                 }
33             }
34             
35             return false;
36         }
37 



posted @ 2009-04-22 17:53  Z.W.  阅读(1124)  评论(2编辑  收藏  举报