Data BindIng简单的说就是当绑定源属性发生变化时,Flex 会把绑定源变化后属性的值赋给目的物的属性。做到了数据同步。
Data BindIng 什么时候发生:
1.在绑定源属性值发生改变时发生。
2.在绑定源发出
initialize事件时绑定发生一次。
让属性具有可绑定功能:
一般的,只要在属性前加上
[Bindable] 或
[Bindable(event="eventname")]
[Bindable(event="eventname")]
元标记即可
注意:
如果没有标出触发绑定的事件,正如[Bindable],Flex会自动为绑定加上
propertyChange事件,当源数据发生变化时,Flex将自动派发该事件,触发数据绑定。如果修改后数据和源数据“===”也就是全等,那么Flex将不会触发数据绑定。
如果标出的触发绑定的事件,正如[Bindable(event="eventname")],那么在源数据发生改变的时候,必须dispatch出该事件才能触发数据绑定。不论修改后数据和源数据是否全等,Flex都将会触发数据绑定,需要自己编程控制,例如:
<mx:Script>
<![CDATA[
[Bindable(event="hhhh")]
private var ss:String="aaa";
private function doTest():void
{
ss="bbb";
<![CDATA[
[Bindable(event="hhhh")]
private var ss:String="aaa";
private function doTest():void
{
ss="bbb";
if(ss!=="aaa") / /判断和源数据是否相等,不相等则触发绑定
this.dispatchEvent(new Event("hhhh"));
}
]]>
</mx:Script>
this.dispatchEvent(new Event("hhhh"));
}
]]>
</mx:Script>
<mx:Text text="{ss}"/>
<mx:Button click="doTest()"/>
<mx:Button click="doTest()"/>
如果没有this.dispatchEvent(new Event("hhhh"))这句,那么你点击按钮是没有设么作用的。 另外当申明自定义触发事件时,用ChangeWatcher来监控其变化,发现虽然目的源值变了,但是ChangeWatcher却监控不到变化,同样ChangeWatcher也监控不到非共有变量的变化。关于ChangeWatcher,下面会提到。
绑定函数——Functions,对象——Object,数组——Arrays
函数:
你可以在{}中直接使用函数。例如:<mx:Text text="{Matn.random()*ss}"/>
上面这个没有什么好讲的,关于函数绑定下面这个比较重要:
<mx:Script>
<![CDATA[
public var ss:String="aaa";
[Bindable(event="hhhh")]
private function gg():String
{
return ss;
}
private function doTest():void
{
ss=Math.random().toString();
this.dispatchEvent(new Event("hhhh"));
}
]]>
</mx:Script>
<mx:Text text="{gg()}"/>
<mx:Button click="doTest()"/>
<![CDATA[
public var ss:String="aaa";
[Bindable(event="hhhh")]
private function gg():String
{
return ss;
}
private function doTest():void
{
ss=Math.random().toString();
this.dispatchEvent(new Event("hhhh"));
}
]]>
</mx:Script>
<mx:Text text="{gg()}"/>
<mx:Button click="doTest()"/>
这样给函数加一个[bindable],便使函数具有绑定功能,但是如果不申明自定义触发事件,只能在组件初始化时绑定一次,点击以上按钮是没有什么作用的。大家可以自己试试。
还有getter和setter函数,比较重要,给getter或setter函数加上[bindable],用不着两个都加,加一个就可以了,例如:
<mx:Script>
<![CDATA[
<![CDATA[
public var ss:String="aaa";
[Bindable]
public function get gg():String
{
return ss;
}
public function set gg(value:String):void
{
ss=value;
}
private function doTest():void
{
gg=Math.random().toString();
this.dispatchEvent(new Event("hhhh"));
}
]]>
</mx:Script>
<mx:Text text="{gg}"/>
<mx:Button click="doTest()"/>
[Bindable]
public function get gg():String
{
return ss;
}
public function set gg(value:String):void
{
ss=value;
}
private function doTest():void
{
gg=Math.random().toString();
this.dispatchEvent(new Event("hhhh"));
}
]]>
</mx:Script>
<mx:Text text="{gg}"/>
<mx:Button click="doTest()"/>
同样能达到绑定效果,如果只有一个getter方法,那么要想实现数据绑定,就需要申明自定义触发事件了,大家可以自己试试。
对象:
对象绑定最重要的是搞清楚怎么申明才能使其属性具有绑定功能,例如:
申明对象 NonBindableObject
//[bindable] 先注释掉这行,测试
public class NonBindableObject extends Object
{
public function NonBindableObject() {
super();
}
public var stringProp:String = "String property";
public var intProp:int = 52;
}
public function NonBindableObject() {
super();
}
public var stringProp:String = "String property";
public var intProp:int = 52;
}
绑定
<mx:Script>
<![CDATA[
[Bindable]
public var myObj:NonBindableObject = new NonBindableObject();
<![CDATA[
[Bindable]
public var myObj:NonBindableObject = new NonBindableObject();
[Bindable]
public var anotherObj:NonBindableObject =
new NonBindableObject();
public var anotherObj:NonBindableObject =
new NonBindableObject();
public function initObj():void {
anotherObj.stringProp = 'anotherObject';
anotherObj.intProp = 8;
}
]]>
</mx:Script>
anotherObj.stringProp = 'anotherObject';
anotherObj.intProp = 8;
}
]]>
</mx:Script>
<mx:Text id="text1" text="{myObj.stringProp}"/>
<mx:Text id="text2" text="{myObj.intProp}"/>
<mx:Button label="改变 myObj.stringProp"
click="myObj.stringProp = 'new string';"/>
<mx:Button label="改变 myObj.intProp"
click="myObj.intProp = 10;"/>
<mx:Button label="Change myObj"
click="myObj = anotherObj;"/>
click="myObj.stringProp = 'new string';"/>
<mx:Button label="改变 myObj.intProp"
click="myObj.intProp = 10;"/>
<mx:Button label="Change myObj"
click="myObj = anotherObj;"/>
如果在申明对象时没有在类前加上[bindable]标签,那么该对象的所有属性是不能被绑定的,也就是说当对象属性发生变化时,不会触发绑定,所以点击前两个按钮都是没有用的,只有当该对象本身发生变化时,才能够触发绑定,正如第三个按钮的操作。
现在取消第一行的注释,使对象属性可绑定,那么再点前两个按钮试试。只要给对象加上[Bindable]元标记,那么会使该对象的所有公有属性——public和拥有getter和setter方法的属性具有绑定功能。
数组:
如果把数组作为绑定对象,那么最好使用ArrayCollection对象,因为当使用ArrayCollection对象的一些API来操作数组会触发数据绑定,如:
ArrayCollection.addItem(),
ArrayCollection.addItemAt(),
ArrayCollection.removeItem(), and
ArrayCollection.removeItemAt()方法
,不然要直接使用Array的话,只用当Array本身发生变化时才触发数据绑定,当数组中某一属性发生变化时是不会触发数据绑定的。例如:
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var myAC:Array =["One", "Two", "Three", "Four"];
[Bindable]
public var myAC2:Array =["One1", "Two1", "Three1", "Four1"];
]]>
</mx:Script>
<mx:Text id="text1" text="{myAC[0]}"/>
<mx:Text id="text2" text="{myAC.getItemAt(0)}"/>
<mx:Button id="button1"
label="改变某一属性"
click="myAC[0]='new One'"/>
<mx:Button id="button2"
label="改变对象"
click="myAC=myAC2"/>
public var myAC:Array =["One", "Two", "Three", "Four"];
[Bindable]
public var myAC2:Array =["One1", "Two1", "Three1", "Four1"];
]]>
</mx:Script>
<mx:Text id="text1" text="{myAC[0]}"/>
<mx:Text id="text2" text="{myAC.getItemAt(0)}"/>
<mx:Button id="button1"
label="改变某一属性"
click="myAC[0]='new One'"/>
<mx:Button id="button2"
label="改变对象"
click="myAC=myAC2"/>
当使用[]形式来申明数组时,必须使用ArrayCollection的API方法来实现数据绑定,所以当你点击第一个按钮时,text2发生了改变,而text1没有。
内容太多,下一篇继续讲。