深入数据绑定

数据绑定是个数据链接。当绑定对象内容发生变化时,被绑定对象接收到事件而自动更新。常用绑定方式有以下几种:
1、MXML的{}方式,如:{myInput.text}{myVar1+myVar2}{myBtn}
2、MXML的<mx:Binding>方式。和{}相同,可以多绑一,可以双向绑定。如<mx:Binding source="myInput.text" destination="myBtn.label"/>
3、AS的mx.binding/utils.BindingUtils类
(1)bindProperty () 方法
public static function bindProperty(site:Object, prop:String, host:Object, chain:Object, commitOnly:Boolean = false):ChangeWatcher
将公用属性(site Object 上的 prop)绑定到可绑定属性或属性链。如果已成功创建 ChangeWatcher 实例,则 prop 将初始化为 chain 的当前值。

参数
site:Object — 定义绑定到 chain 的属性的 Object。 
prop:String — 在要绑定的 site Object 中定义的公用属性的名称。当 chain 值更改时,该属性将接收 chain 的当前值。 
host:Object — 用于承载要监视的属性或属性链的对象。 
chain:Object — 用于指定要监视的属性或属性链的值。合法值包括:
   包含宿主对象公用可绑定属性名称的字符串。
   以下格式的 Object:{ name: 属性名, getter: function(host) { return host[property name] } }。此 Object 必须包含宿主对象的公用可绑定属性的名称和用于该属性的 getter 函数。
   包含前两个选项的组合的非空 Array,该数组表示可从宿主访问的可绑定属性链。例如,要绑定属性 host.a.b.c,需按以下形式调用此方法:bindProperty(host, ["a","b","c"], ...)。
   请注意:在 chain 参数中命名的属性必须是公用属性,因为 describeType() 方法抑制非公用属性的所有相关信息,包括 ChangeWatcher 在查找为给定属性公开的 change 事件时扫描的可绑定元数据。但是,在使用上述 { name, getter } 参数形式时提供的 getter 函数可用于将任意计算值与指定的(公用)属性关联。
commitOnly:Boolean (default = false) — 如果仅在提交 change 事件时需要调用处理函数,则设置为 true;如果无论是否提交 change 事件都调用处理函数,则设置为 false。请注意:属性是否存在不提交的 change 事件由 [NonCommittingChangeEvent(<event-name>)] 元数据标记来指示。通常,这些标记用于指示细化值更改,例如确认前在文本字段中进行的修改。 
返回 ChangeWatcher — 如果已为 chain 参数指定了至少一个属性名称,则返回 ChangeWatcher 实例;否则返回 null。 
如BindingUtils.bindProperty(myBtn,"label",myTextInput,"text");
(2)bindSetter () 方法  
public static function bindSetter(setter:Function, host:Object, chain:Object, commitOnly:Boolean = false):ChangeWatcher
将 setter 函数(setter)绑定到可绑定属性或属性链。如果已成功创建 ChangeWatcher 实例,则使用 chain 的当前值调用 setter 函数。
参数
setter:Function — chain 的当前值更改时使用该值的参数进行调用的 Setter 方法。 
host:Object — 属性的宿主。有关详细信息,请参阅 bindProperty() 方法。 
chain:Object — 属性或属性链的名称。有关详细信息,请参阅 bindProperty() 方法。 
commitOnly:Boolean (default = false) — 如果应仅在提交 change 事件时调用处理函数,则设置为 true。有关详细信息,请参阅 bindProperty() 方法。
返回 ChangeWatcher — 如果已为 chain 参数指定了至少一个属性名称,则返回 ChangeWatcher 实例;否则返回 null。 
如BindUtils.bindSetter(setTextInput,myTextInput,"text");
public function setTextInput(myStr:String):void{
   myBtn.label=myStr;
}
4、AS的mx.binding.utils.ChangeWatcher
watch () 方法  
public static function watch(host:Object, chain:Object, handler:Function, commitOnly:Boolean = false):ChangeWatcher
创建并启动 ChangeWatcher 实例。一个 ChangeWatcher 实例可观察一个属性或一个属性链。属性链是可从宿主对象访问的一系列属性。例如,表达式 obj.a.b.c 中包含属性链 (a, b, c)。
参数
host:Object — 用于承载要监视的属性或属性链的对象。创建 ChangeWatcher 实例后,您可以使用 reset() 方法更改 host 参数的值。
chain:Object — 用于指定要监视的属性或属性链的值。合法值包括:
   包含宿主对象公用可绑定属性名称的 String。
   以下格式的 Object:{ name: 属性名, getter: function(host) { return host[name] } }。此 Object 包含一个公用可绑定属性的名称以及一个充当该属性的 getter 的函数。
   包含前两种选项的任意组合的非空 Array。这代表可从宿主访问的可绑定属性链。例如,要观察属性 host.a.b.c,需按以下形式调用此方法:watch(host, ["a","b","c"], ...)。
请注意:在 chain 参数中命名的属性必须是公用属性,因为 describeType() 方法抑制非公用属性的所有相关信息,包括 ChangeWatcher 在查找为给定属性公开的 change 事件时扫描的可绑定元数据。但是,在使用上述 { name, getter } 参数形式时提供的 getter 函数可用于将任意计算值与指定的(公用)属性关联。
handler:Function — 在修改观察属性(或观察链中任何属性)的值时调用的事件处理函数。如果观察器链中的任何宿主对象调度了在该宿主对象的 [Bindable] 元数据标记中为相应的观察属性指定的事件,则表明已经修改。默认事件名为 propertyChange。
由可绑定属性调度的事件对象将传递到此处理函数,不会进行任何修改。默认情况下,Flex 将调度 PropertyChangeEvent 类型的事件对象。然而,在使用 [Bindable] 元数据标记定义可绑定属性时,您可以定义自己的事件类型。
commitOnly:Boolean (default = false) — 如果仅在提交 change 事件时需要调用处理函数,则设置为 true;如果无论是否提交 change 事件都调用处理函数,则设置为 false。请注意:属性是否存在不提交的 change 事件由 [NonCommittingChangeEvent(<event-name>)] 元数据标记来指示。通常,这些标记用于指示细化值更改,例如确认前在文本字段中进行的修改。
返回 ChangeWatcher — 如果已为 chain 参数至少指定了一个属性名称,则返回 ChangeWatcher 实例;否则返回 null。请注意,不能保证返回的监视程序已成功发现 change 事件并将自身附加到 change 事件,因为宿主可能没有在给定的属性或属性链上公开任何事件。您可以使用 isWatching() 方法来确定观察器的状态。
5、为自己的类或属性添加绑定功能,使用[Bindable]标签
(1)类前使用[Bindable]表示所有属性都支持绑定,此类必须实现IEventDispatcher接口。
(2)可以给变量声明前或变量getter setter前使用[Bindable]。如果getter和setter方法同名,那么给其中一个[Bindable],相当于给两个都用了[Bindable]。
(3)[Bindable]默认分发的是propertyChange。当一个绑定对象中有很多属性被用作数据绑定时,如果这此属性都使用默认更新事件名会降低程序运行效率。我们可以通过改变更新事件名称来解决这个问题。如
[Bindable(event="myEvent")]
…………
dispatchEvent(new Event("myEvent"));
注:如果只是更改事件名称,无需重新自定义事件。
6、可以绑定到一个动态类的属性上。具体参考FLEX COOKBOOK第14章第9节。贴一下代码:
package com.oreilly.flexcookbook
{
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;

[Event(name="complete", type="flash.events.Event")]
[Bindable(event="propertyChange")]
dynamic public class Properties extends Proxy implements IEventDispatcher
{
private var _evtDispatcher:EventDispatcher;
private var _data:XML;
private var _loader:URLLoader;
public static const COMPLETE:String = "complete";

public function Properties()
{
_evtDispatcher = new EventDispatcher();
}

// load external xml.
public function loadProperties( fnm:String ):void
{
_loader = new URLLoader();
_loader.addEventListener( Event.COMPLETE, loadHandler );
_loader.load( new URLRequest( fnm ) );
}

// set data property and dispatch 'complete' notification.
private function loadHandler( evt:Event ):void
{
data = XML( _loader.data );
dispatchEvent( new Event( Properties.COMPLETE ) );
}

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 "";
else return _data..property.(@id == String( name ) );
}

// use E4X to modify property value on xml. Dispatch'propertyChange'
override flash_proxy function setProperty( name:*, value:*):void
{
var oldVal:String = _data..property.(@id == String( name) );
var index:Number = _data..property.(@id == String( name )).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 );
}

}
}


<mx:Application
xmlns:mx="
http://www.adobe.com/2006/mxml"
layout="vertical"
creationComplete="initHandler();">
<mx:Script>
<![CDATA[
import mx.binding.utils.BindingUtils;
import com.oreilly.flexcookbook.Properties;

private var _properties:Properties;

// create proxy and load xml.
private function initHandler():void
{
_properties = new Properties();
_properties.addEventListener( Event.COMPLETE,propertiesHandler );
_properties.loadProperties( "data/properties.xml" );
}

// xml data loaded. establish data binding.
private function propertiesHandler( evt:Event ):void
{
BindingUtils.bindProperty( nameOutput, "text", _properties, "name" );
BindingUtils.bindProperty( albumOutput, "text", _properties, "album" );
BindingUtils.bindProperty( genreOutput, "text", _properties, "genre" );
}

// change properties of proxied data.
private function changeHandler():void
{
_properties.name = nameField.text;
_properties.album = albumField.text;
_properties.genre = genreField.text;
}
]]>
</mx:Script>
<mx:Label text="Data Loaded." />
<mx:Form>
<mx:FormItem label="Name:">
<mx:Text id="nameOutput" />
</mx:FormItem>
<mx:FormItem label="Album:">
<mx:Text id="albumOutput" />
</mx:FormItem>
<mx:FormItem label="Genre:">
<mx:Text id="genreOutput" />
</mx:FormItem>
</mx:Form>
<mx:HRule width="100%" />
<mx:Form>
<mx:FormItem label="Name:">
<mx:TextInput id="nameField" />
</mx:FormItem>
<mx:FormItem label="Album:">
<mx:TextInput id="albumField" />
</mx:FormItem>
<mx:FormItem label="Genre:">
<mx:TextInput id="genreField" />
</mx:FormItem>
<mx:FormItem label="Submit Changes">
<mx:Button label="ok" click="changeHandler();" />
</mx:FormItem>
</mx:Form>
</mx:Application>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值