flex Data Binding

数据绑定发生的时机
1.当源数据属性已经改变,数据绑定源发出一个事件,这个事件可以在应用执行的任何时候发出,这个事件会触发
Flex将源属性的值复制到目的属性中
2.在应用启动过程中,当源对象发出initialize事件时,所有数据绑定都一次性的被触发以初始化
目的属性,如果源属性是只读的或者静态的常量,那么就只有这一次机会会自动执行这个数据绑定
3.通过程序控制绑定,UIComponent类的executeBindings()方法可以让Flex执行以UIComponents为目的
上的所有绑定,所有容器和控件,以及Repeater组件都是从UICompoent类继承的,Container类和REpeater类的
executeChildBindings()方法可以让自己及其所有子对象上的所有绑定执行,所有容器都是从Container类继承
只有在确保绑定没有自动发生时才能使用executeBindings()方法


[Bindable]元数据标签通过三种方式:
1.在类中定义使用
package com.demo
{
import flash.events.EventDispatcher;
[Bindable]
public class DataObject extends EventDispatcher{

}
}
2.在字段中使用
[Bindable] private var _lastName:String;
3.在方法中使用

<fx:Declarations>
<mx:CurrencyFormatter id="formatter" precision="2" />
</fx:Declarations>
<s:RichText text="{formatter.format( amtInput.text )}" />

4.字段set 监听 绑定自定义事件

<fx:Declarations>
<s:ArrayCollection id="fruitCollection">
<fx:String>Apple</fx:String>
<fx:String>Banana</fx:String>
<fx:String>Orange</fx:String>
</s:ArrayCollection>
</fx:Declarations>
<fx:Script>
<![CDATA[
private var _selectedFruit:String;
[Bindable(event="Demo")]
private function isOrangeChosen():Boolean
{
return _selectedFruit == "Orange";
}
public function get selectedFruit():String
{
return _selectedFruit;
}
public function set selectedFruit( value:String ):void
{
_selectedFruit = value;
dispatchEvent( new Event( "Demo" ) );
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout />
</s:layout>
<s:Label text="Select a Fruit:" />
<s:HGroup>
<s:DropDownList id="fruitCB"
dataProvider="{fruitCollection}"
change="{selectedFruit = fruitCB.selectedItem}" />
<s:Button label="eat the orange."
enabled="{isOrangeChosen()}" />
</s:HGroup>



4.双向绑定

<s:VGroup>
<s:Label text="From Input 2:" />
<s:TextInput id="input1" text="{input2.text}" />
<s:Label text="From Input 1:" />
<s:TextInput id="input2" text="{input1.text}" />
</s:VGroup>


<s:VGroup>
<s:Label text="From Input 2:" />
<s:TextInput id="input1" text="@{input2.text}" />
<s:Label text="From Input 1:" />
<s:TextInput id="input2" />
</s:VGroup>


<fx:Binding source="input1.text" destination="input2.text" twoWay="true" />
<!-- source 源属性
-- destination 目标属性
-->
<s:VGroup>
<s:Label text="From Input 2:" />
<s:TextInput id="input1" />
<s:Label text="From Input 1:" />
<s:TextInput id="input2" />
</s:VGroup>


5.使用 BindingUtils 绑定 定义绑定观察者 (watchers)

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="handleCreationComplete();">
<fx:Script>
<![CDATA[
import mx.binding.utils.BindingUtils;
import mx.binding.utils.ChangeWatcher;
private var nameWatcher:ChangeWatcher;
private function handleCreationComplete():void
{
nameWatcher = BindingUtils.bindProperty( nameField, "text",
nameInput, "text" );
}
private function handleClick():void
{
if( nameWatcher.isWatching() )
{
nameWatcher.unwatch();
btn.label = "watch";
}
else
{
nameWatcher.reset( nameInput );
btn.label = "unwatch";
}
}
]]>

</fx:Script>
<s:Panel title="User Entry.">
<s:layout>
<s:VerticalLayout paddingLeft="5" paddingRight="5"
paddingTop="5" paddingBottom="5" />
</s:layout>
<s:HGroup verticalAlign="bottom">
<s:Label text="Name:" />
<s:TextInput id="nameInput" />
</s:HGroup>
<s:HGroup verticalAlign="bottom">
<s:Label text="You Entered:" />
<s:RichText id="nameField" />
</s:HGroup>
<s:Button id="btn"
label="unwatch"
click="handleClick();" />
</s:Panel>
</s:Application>

<fx:Binding source="textInput1.text"
destination="textInput2.text"
twoWay="false" />



5.1 使用@ 符号绑定数据

<s:TextInput id="textInput2" text="@{text}" />


6.获取xml中相关数据

<mx:Binding source="myTI.text" destination="myText.text"/>
<fx:XML id="itemData" xmlns="">

<fx:Binding source="{itemData..item.(@id == '1').name} {itemData..item.(@id ==
'1').description.toLowerCase()}" destination="lab.text" />


-- 绑定一个Object对象 当然这个类只要继承 Object

private var obj:Object = {name:'Tom Waits',
album:'Rain Dogs',
genre:'Rock'};
[Bindable]
private var proxy:ObjectProxy = new ObjectProxy( obj );
private function handleClick():void
{
proxy.name = nameField.text;
proxy.album = albumField.text;
proxy.genre = genreField.text;
}



package com
{
[Bindable]
public class BindableObject extends Object {
public var stringProp:String = "String property";
public var intProp:int = 52;
public function BindableObject() {
super();
}
}
}



<fx:Declarations>
<fx:Script>
<![CDATA[
import com.BindableObject;
[Bindable]
public var myObj:BindableObject = new BindableObject();
[Bindable]
public var anotherObj:BindableObject =new BindableObject();
public function initObj():void {
anotherObj.stringProp = 'anotherObject';
anotherObj.intProp = 8;
}
]]>
</fx:Script>
</fx:Declarations>
<mx:Text id="text1" text="{myObj.stringProp}"/>
<mx:Text id="text2" text="{myObj.intProp}"/>
<mx:Button label="Change myObj" click="myObj = anotherObj;"/>

7.动态绑定 extends Proxy implements IEventDispatcher

package com
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.utils.Proxy;
import flash.utils.flash_proxy;
import mx.events.PropertyChangeEvent;
[Bindable(event="propertyChange")]
dynamic public class Properties extends Proxy implements IEventDispatcher
{
private var _evtDispatcher:EventDispatcher;
private var _data:XML;
public function Properties( source:XML )
{
_evtDispatcher = new EventDispatcher();
data = source;
}
public function get data():XML
{
return _data;
}
public function set data( xml:XML ):void
{
_data = xml;
}
// use E4X to return property value held on XML
override flash_proxy function getProperty( name:* ):*
{
if( _data == null ) return "";
var attributeValue:String = QName( name ).toString();
var value:* = _data..property.(@id == attributeValue );
return value;
}
// use E4X to modify property value on XML, and dispatch 'propertyChange'
override flash_proxy function setProperty( name:*, value:* ):void
{
var attributeValue:String = QName( name ).toString();
var oldVal:String = _data..property.(@id == attributeValue );
var index:Number = _data..property.(@id == attributeValue ).
childIndex();
_data.replace( index, <property id={name}>{value}</property> );
var evt:Event = PropertyChangeEvent.createUpdateEvent( this, name,
oldVal, value );
dispatchEvent( evt );
}
// IEventDispatcher implementation
public function addEventListener( type:String,
listener:Function,
useCapture:Boolean = false,
priority:int = 0,
useWeakReference:Boolean = false):void
{
_evtDispatcher.addEventListener( type, listener, useCapture,
priority, useWeakReference );
}
// IEventDispatcher implementation
public function removeEventListener( type:String,
listener:Function,
useCapture:Boolean = false ):void
{
_evtDispatcher.removeEventListener( type, listener, useCapture );
}
// IEventDispatcher implementation
public function dispatchEvent( evt:Event ):Boolean
{
return _evtDispatcher.dispatchEvent( evt );
}
// IEventDispatcher implementation
public function hasEventListener( type:String ):Boolean
{
return _evtDispatcher.hasEventListener( type );
}
// IEventDispatcher implementation
public function willTrigger( type:String ):Boolean
{
return _evtDispatcher.willTrigger( type );
}
}
}




<fx:Declarations>
<fx:XML id="propertiesData" source="assets/properties.xml" />
<!-- 这个xml资源可以是一个url -->
<!-- 基本格式如下
<fx:XML id="propertiesData" xmlns="">
<properties>
<property id="name">Tom Waits</property>
<property id="album">Rain Dogs</property>
<property id="genre">Rock</property>
</properties>
</fx:XML>
-->
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.Properties;
import mx.binding.utils.BindingUtils;
private var properties:com.Properties;
private function handleCreationComplete():void
{
properties = new Properties( propertiesData );
establishBindings();
}
private function establishBindings():void
{
BindingUtils.bindProperty( nameOutput, "text",
properties, "name" );
BindingUtils.bindProperty( albumOutput, "text",
properties, "album" );
BindingUtils.bindProperty( genreOutput, "text",
properties, "genre" );
}
private function handleSubmit():void
{
properties.name = nameInput.text;
properties.album = albumInput.text;
properties.genre = genreInput.text;
}
]]>
</fx:Script>
<s:Button label="ok" click="handleSubmit();" />

8.绑定数组


<fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var myAC:ArrayCollection = new ArrayCollection(["One", "Two", "Three", "Four"]);
[Bindable]
public var myAC2:ArrayCollection = new ArrayCollection(["Uno", "Dos", "Tres", "Quatro"]);
]]>
</fx:Script>
</fx:Declarations>
<mx:Text id="text1" text="{myAC[0]}"/>
<mx:Text id="text2" text="{myAC.getItemAt(0)}"/>


9.绑定Model
<mx:String id="areaCode">707</mx:String>
<mx:Model id="model">
<info>
<name>
<firstName>Tim</firstName>
<lastName>O'Reilly</lastName>
</name>
<email>tim@oreilly.com</email>
<phone>{areaCode}827-7000</phone>
</info>
</mx:Model>
<mx:Binding source="model.phone" destination="nameLabel.text"/>
<mx:Label id="nameLabel"/>


使用[Bindable元数据标记]
1.在public 类中定义之前使用
在这个地方使用[Bindable]使得类中定义的全部public变量以及同时具有的set get方法
的public 属性能成为数据绑定表达式的源,在这中情况下,[Bindable]不使用任何参数
[Bindable]
public class MyDemo{}
在public class 之前使用[Bindable]只是将绑定作用与public属性,它不会作用与private 和
protected属性以及那些定义其他namespace中的属性,必须在非public属性前插入[Bindable]
标记才能成为数据绑定的源。
2.在public,protected 或者private 属性之前使用
在public,protected或者private属性之前使用[Bindable]可以将这个特定的属性定义为支持数据绑定的
例如:
[Bindable]
private var demo:String;
[Bindable (event="nameChanged")]
public var name:String ;
flex编译器自动为那个属性名产生 propertyChange,类型瓦尔PropertyChangeEvent的事件
如果写入的属性不变,那么flex不会发出事件或者更新属性。
3.在由get set 方法所有定义public ,private 或protected属性之前使用
在这种情况下使用 [Bindable]必须同时为属性定义get set 方法,如果只有一个set 方法,那么就创建了一个只写的属性,这个的属性不能
作为数据源绑定,如果只定义了一个set 方法那么就创建了一个只读的属性,把只读属性当作数据源绑定而不是用
[Bindable]标记,就相当于使用了一个const关键字定义的变量来作为数据绑定的源;这样的属性只能在引用启动时触发绑定一次,以后就不会在触发
[Bindable]
public function set demo(value:String):void
{
this.demo=value;
}

4.关于绑属性事件的方法
[Bindable(event="changeName")]
public function set name(value:String):void
{
//创建并分发事件
dispatchEvent(new Event("changeName"));
}
public function get name():String
{

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值