使用数据绑定时,Flex 会自动把一个对象的数据复制,提供给另一个对象使用,提供数据一方称为数据源对象,使用数据的一方称为目标对象。当数据源对象的数据发生变化时,目标对象的数据会自动更新。
实 质上,绑定的实现也是借助事件机制来完成的,当目标使用了数据绑定,目标对象就会侦听数据源的某一个固定事件。如果数据源改变,就派发事件,通知目标对象 更新最新数据。当然这个过程都是由Flex来完成。作为绑定的数据源对象,必须支持绑定--对象有派发改变事件的能力。
Data BindIng 什么时候发生: 1.在绑定源属性值发生改变时发生。 2.在绑定源发出initialize事件时绑定发生一次。
1>>使用数据绑定的多数情况:
1、将后台数据(通过Web Service 或 Remoting 方式得到的数据)绑定给控件
2、把控件数据绑定给后台通信对象,发送给后台服务端
3、后台返回数据和数据模型 进行绑定
4、组件或对象属性的数据绑定
2>>数据绑定的方式有:
1) [Bindable] 标签
也就是[Bindable(event="propertyChange")]的简称。还可以指定[Bindable(event="eventname")]。
2) {},如果是双向绑定,则{@}
比如:backgroundColor="{mColor.value.toString()}" 双向绑定的话,就是backgroundColor="{@mColor.value.toString()}"
AS:text="{(Number(age_txt.text)>= 16)?'成年':'未成年'}"
函数: scaleX="{doResize(scale)}"
3) mxml标签 <mx:Binding source="" destination="">
如果是双向绑定,则<mx:Binding source="" destination="" twoway="true">
比如:<mx:Binding source="users.user.blogURL" destination="pic.toolTip" />
双向绑定的话:<mx:Binding source="users.user.blogURL" destination="pic.toolTip" twoway="true"/>
4) AS类: mx.binding.utils.BindingUtils 动态绑定
有时你的视图组件是动态生成的,有时你需要动态的改变绑定,有时你使用Sprite动态生成的图形也需要绑定数据,或者你就是喜欢完全使用AS来写。
比如:
private function init():void {
for (var i : int = 0; i < 3; i++) {
var nameLabel : Label = new Label();
var emailLabel : Label = new Label();
myBox.addChild(nameLabel);
myBox.addChild(emailLabel);
BindingUtils.bindProperty(nameLabel, "text", userVO, "name");
BindingUtils.bindProperty(emailLabel, "text", userVO, "email");
}
}
使用这种方法,可以将多个视图组件与一个Value Object对象(或叫DTO、Bean等)进行绑定,当VO对象改变时,所有绑定的视图都会改变。也可以在纯as文件中实现动态绑定了。
3>>可以对变量,类,getter 和setter 进行绑定
getter/setter。
是不是public没有关系,private的就只能给自家用呗。用在Class上就是简单的给所有的public属性(包括变
量,getter/setter,普通方法)加上[Bindable],可是一般的方法不能用[Bindable],于是一般就能看到flex给了个
warning,直接无视。变量就是上面讲的。
用在只读,只写属性(getter/setter)上面,因为getter和setter很像方法,用起来会有点不同。看看这个例子:
[Bindable]
private var content:Array = new Array();
[Bindable]
public function set _content(ct:String):void
{
content = ct.split(SEP);
}
[Bindable]
public function get _wholeText():String
{
if(content.length == 0)
{
return "";
}
else
{
var _w:String = "";
for(var i:int=0 ; i<content.length ; i++)
{
_w += content[i] + "\r\n";
}
return _w;
}
}
原来的设想是content绑定_wholeText,可它是不工作的。为什么?_wholeText太复杂了,被编译器排除在“可能”之外,编译器认为
没有绑定关系,如果只是简单的return
content,倒是可以的。说白了就是为了降低复杂度和提高效率,复杂情况的getter会被忽略。如何解决?可以手动建立绑定,即
[Bindable("eventName")]。把代码改成这样:
[Bindable]
private var content:Array = new Array();
[Bindable]
public function set _content(ct:String):void
{
content = ct.split(SEP);
this.dispatchEvent(newEvent("_contectChanged"));
}
[Bindable(event="_contectChanged")]
public function get _wholeText():String
{
if(content.length == 0)
{
return "";
}
else
{
var _w:String = "";
for(var i:int=0 ; i<content.length ; i++)
{
_w += content[i] + "\r\n";
}
return _w;
}
}
这样就避免了编译器去自动识别。自己加上绑定关系,当_content被赋值,发出_contentChanged事件,通知所有被绑定的getter方法执行一遍。这也说明了,绑定不过是事件游戏而已,flex为用户隐藏了很多底层算法。