说到Flex的数据绑定,不得不提到[Bindable]和BindingUtils,两者都是基于Flex的事件机制,前者的用法请参考我的另一篇文章http://blog.csdn.net/rzhzhz/article/details/7057759,现在我们重点来探讨下BindingUtils的用法,其实刚开始用BindingUtils这个类的时候,是用在两个不同的组件之间的属性绑定,没有仔细去探究过其原理。然而当用到自定义类的属性绑定的时候就出现了绑定失效的问题,那么原因在哪呢?
首先我们来看看BindingUtils的源码
public static function bindProperty(
site:Object, //定义绑定到chain属性的对象
prop:String, //在要绑定的 site 对象中定义的公用属性(可以是public属性名或者public setter函数的函数名)。 当 chain 值更改时,该属性将接收 chain 的当前值 。
host:Object, //用于承载要监视的属性或属性链的对象
chain:Object, //要监视的属性(可以是public属性名或者public setter函数的函数名)或属性链的值
commitOnly:Boolean = false //如果仅在提交 change 事件时需要调用处理函数,则设置为 true,否则设置为false
):ChangeWatcher //如果已为 chain 参数指定了至少一个属性名称,则返回 ChangeWatcher 实例;否则返回 null
{
var w:ChangeWatcher =
ChangeWatcher.watch(host, chain, null, commitOnly); //获得ChangeWatcher实例
if (w != null)
{
var assign:Function = function(event:*):void
{
site[prop] = w.getValue(); //获得chain值并设置到site对象prop属性
};
w.setHandler(assign);
assign(null);
}
return w;
}
public static function bindSetter(setter:Function, //chain的当前值改变时使用改值的参数进行调用的Setter方法
host:Object, //用于承载要监视的属性或属性链的对象
chain:Object, //要监视的属性(可以是public属性名或者public setter函数的函数名)或属性链的值
commitOnly:Boolean = false //如果仅在提交 change 事件时需要调用处理函数,则设置为 true,否则设置为false
):ChangeWatcher //如果已为 chain 参数指定了至少一个属性名称,则返回 ChangeWatcher 实例;否则返回 null
{
var w:ChangeWatcher =
ChangeWatcher.watch(host, chain, null, commitOnly); //获得ChangeWatcher实例
if (w != null)
{
var invoke:Function = function(event:*):void
{
setter(w.getValue()); ////获得chain值并调用setter方法(此setter方法可以为任意函数,但参数必须为获得的value值类型)
};
w.setHandler(invoke);
invoke(null);
}
return w;
}
根据源码我们能看到实现绑定的对象为ChageWatcher,它相当于一个监视者,ChageWatcher调用静态watch函数时所做的事有:
1.获得ChangeWatcher实例,ChangeWatcher实例可以是对单个属性或者属性链的监视,如果是属性链,则该监视第一层属性的ChangeWatcher会包含监视下一层属性的ChangeWatcher的引用,依次往下类推。
2.调用ChangeWatcher实例的reset方法,reset所做的事有(可参考ChangeWatcher源码,此处不再粘贴)
(1).获得chain的所有change事件(PropertyChangeEvent)(因为要派发PropertyChangeEvent事件,chain属性或setter方法必须用[Bindable]声明)
(2).依次为host添加监听器,监听chain的change事件(因为要添加监听器,故host对象必须实现IEventDispatcher接口)
(3).如果ChangeWatcher实例包含对下一层属性ChangeWatcher实例的引用,则调用下一层属性ChangeWatcher实例的reset方法
3.返回监视第一层属性的ChangeWatcher
上面说到为host添加监听器监听chain的change事件,下面我们来看看监听器的事件处理器函数:
1.首先判断ChangeWatcher实例是否包含对下一层属性ChangeWatcher实例的引用,如果包含则调用下一层属性ChangeWatcher实例的reset方法
2.调用handler函数处理最终结果,hander函数为ChangeWatcher实例setHandler函数所设置的function(setHandler时会为每一层属性的ChangeWatcher实例设置处理函数)
下面我们总结下要实现绑定需要满足什么条件
host 1.host对象必须继承IEventDispatcher接口
2.chain public属性或public setter方法必须用[Bindable]声明,或者在整个类声明上添加[Bindable]声明
site 调用bindProperty函数时,prop 必须为public属性或public setter方法
setter 调用bindSetter函数时,setter方法名可以为任意,但参数必须为chain的value类型