用于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;
}
分享到:
相关推荐
Flex 组件Flex 组件Flex 组件Flex 组件Flex 组件
flex数据绑定的原理
flex中的datagrid是一个重量级的组建,也是数据绑定中的主要组件之一。
flex页面跳转及数据绑定的方法,flex页面跳转及数据绑定的方法
flex 高级自定义组件 需要重写的方法,以及为什么要重写,何时调用等。
Flex4自定义组件 介绍了flex中如何自定义组件以及相关应用
详解Flex4的系统组件与基本组件。让你在应用的时候知道用什么.
数据绑定内容简介: 现在数据库或是某个文件里有一些数据需要显示在界面上该怎么办呢?我们的目的就是将这些数据设法放到界面上去可以显示出来,这个将数据放到界面上去的... 在Flex应用中程序中,数据绑定的实际是借
Flex3组件介绍,包含flex3的所有组件介绍并有例子
Flex各自定义组件事件通讯例子,简单的用户登录和组件之间的跳转!
这个是我一直在用的针对于组件全屏的一个类,这里是页面上的某个组件全屏,而不是整个页面全屏。 这是原始的库了,里面少了一个针对按下ESC键的处理,这个在使用的时候可以自己加,另外一个问题就是由于这个库是FLEX...
flex组件之数据可视化组件实例源码 包括多种chart,共27个实例
用数据动态绑定XML,然后实现flex中树的绑定
数据绑定是Flex的关键这本电子数详细介绍有关Flex绑定的知识
Flex3组件拖放教程,该组件是flex组件中最有特色的
flex4中tree组件分层显示数据示例代码(可直接运行)
支持手动拖拽缩放flex组件的组件,com.janisRadins.zip
java flex 对象定义 数据类型定义
Adobe Flex Builder 3 中组件之间的参数传递(主要是给大家学习)
很通用的Flex 分页组件,经过本人测试,可以应用到项目中,很方便