相信只要开发过Flex应用程序的读者都已经使用过数据绑定(Data Binding),数据绑定是Flex非常重要的特性之一,它就像一种魔法一样,能快速让你将应用程序中两个不同的部份通过数据绑定联系起来,大大提高了 开发的效率,这也是让Flex如此流行的特性之一。大多时候我们并不需要了解数据绑定背后的机制,然而,随着在Flex应用程序规模不断增大,数据绑定特 性也被开发人员使用得越来越多,其带来的问题也逐渐显现出来,正因为它像魔法一样,使用起来非常简单,因而很多开发人员并未去深入了解数据绑定背后的工作 机制,致使在应用中使用不合理,这样不仅会给应用程序带来性能上的问题,也会使得程序难以维护,甚至可能带来不可预料的Bug,很难跟踪处理。
本节首先会简要介绍数据绑定的基本概念及其常见应用,然后带领大家深入“幕后”,剖析”魔法”倒底是怎样产生的,最后在最佳实践部分给大家介绍一下在实际运用数据绑定时常犯的错误及纠正方案。
Flex数据绑定简介与常见应用¶
数据绑定是这样一种特性,它能方便的让一个对象的数据自动反映到另外一对象的数据上,通常需要我们提供“数据源属性”和”数据目标属性“,有了源与 目标,当我们使用数据绑定特性时,它会自动帮我们把”数据源属性“的值拷贝到“数据目标属性“值中去。本质上来说,Flex绑定功能的实现也是对事件机制 的运用体现,在后序文章:数据绑定背后的故事部分会详细阐述这一点。
Flex为我们提供了多种使用数据绑定的方式,归纳起来通常有以下几种:
- {}绑定实现
- <Binding />标记绑定实现
- 应用BindingUtil类绑定实现
- ChangeWacher绑定实现
- [Bindable]元标签绑定实现
- 双向绑定
下面以一非常简单的程序为例,以不同的数据绑定方式来实现同样的绑定功能,以便读者能对比不同数据绑定实现方式之间的不同之处。
最终程序运行效果如图所示,当我们在上面的文字输入框输入文字时,借助绑定的功能,下面的文字输入框将同步显示在上面输入框输入的内容:
{}数据绑定运行效果
{}绑定实现
完整程序源码如下:
DataBindingSample.mxml
1 2 3 4 5 6 7 8 9 10 11 |
<?xml version="1.0" encoding="utf-8"?>
<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">
<s:layout>
<s:VerticalLayout horizontalAlign="center" verticalAlign="middle" />
</s:layout>
<s:TextInput id="txtInputA" />
<s:TextInput id="txtInputB" text="{txtInputA.text}"/>
</s:Application>
|
程序非常简单,{}花括号表明我们希望将txtInputA组件的text值绑定到textInputB的text,这样,当在txtInputA 中输入文字时,输入的内容会自动绑定到txtInputB的输入框中去。短短几句便实现了数据显示同步的功能,这便是绑定的强大功能。
<Binding />标签绑定实现如下面代码所示(此处略去Application标签及布局相关的代码)
1 2 3 |
<fx:Binding source="txtInputA.text" destination="txtInputB.text" />
<s:TextInput id="txtInputA" />
<s:TextInput id="txtInputB" />
|
这里我们使用了Binding标记(本质上<Binding />标记对应的是Binding类),并由source和destination明确的指出绑定的来源及目标。
BindingUtils类绑定实现
使用BindingUtils类进行绑定又包括两种方式:
- BindingUtils.bindProperty()方法主要用来直接绑定源与目标的属性(见下面代码):
DataBindingSample03.mxml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="utf-8"?>
<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="onCreationComplete()">
<fx:Script>
<![CDATA[
import mx.binding.utils.BindingUtils;
private function onCreationComplete():void {
BindingUtils.bindProperty(txtInputB, "text", txtInputA, "text");
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout horizontalAlign="center" verticalAlign="middle" />
</s:layout>
<s:TextInput id="txtInputA" />
<s:TextInput id="txtInputB" />
</s:Application>
|
这里唯一需要注意的是BindingUtils.bindProperty()方法参数的顺序,需要绑定的目标对象及属性在前,而源对象及属性在后。
- BindingUtils.bindSetter()方法指定当绑定源的属性发生改变时去执行指定的函数:
DataBindingSample04.mxml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?xml version="1.0" encoding="utf-8"?>
<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="onCreationComplete()">
<fx:Script>
<![CDATA[
import mx.binding.utils.BindingUtils;
private function onCreationComplete():void {
BindingUtils.bindSetter(setterHandler, txtInputA, "text");
}
private function setterHandler(source:String):void {
txtInputB.text = source;
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout horizontalAlign="center" verticalAlign="middle" />
</s:layout>
<s:TextInput id="txtInputA" />
<s:TextInput id="txtInputB" />
</s:Application>
|
[Bindable]元标签绑定实现
来看另外一个实例,假设我们有一Person的类[见代码Person.as]用来存储firstName和lastName,在主程序中[见代码Behind_DataBinding.mxml],首先创建一Person类实例并分别为firstName和lastName赋值,最后通过绑定将person的值绑定到Label组件显示 出来。当我们点击“Change Name”按钮时,在”click“事件处理函数中改变person的值,此时绑定person的Label标签值也会相应改变。
代码清单 Person.as
1 2 3 4 5 6 7 |
package com.jexchen.model {
[Bindable]
public class Person {
public var firstName:String;
public var lastName:String;
}
}
|
主程序也非常简单,见代码清单Behind_DataBinding.mxml
代码清单 Behind_DataBinding.mxml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?xml version="1.0" encoding="utf-8"?>
<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="onCreationComplete()">
<fx:Script>
<![CDATA[
import com.jexchen.model.Person;
[Bindable]
public var person:Person = new Person();
private function onCreationComplete():void {
person.firstName = "Anthony";
person.lastName = "Lee";
}
private function changeName():void {
person.firstName = "Bruce";
person.lastName = "Chan";
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>
</s:layout>
<s:Label id="firstNameId" text="{person.firstName}" />
<s:Label id="lastNameId" text="{person.lastName}" />
<s:Button label="Change Name" click="changeName()" />
</s:Application>
|
注意到,我们直接在Person类前添加了[Bindable]元标签(直接在类前直接加[Bindable]相当于为类下面所有public属性 添加了[Bindable]元标签),在主程序中,为person实例也添加了[Bindable]元标签,然后将其直接绑定到Label标签用于显示。 这种绑定用法在企业应用开发中很常见,例如在MVC应用模式中,通常会在应用程序中设有称为Model的模型类,Model中存放不同的VO(值对象,如 这里的Person),然后在不同的子组件中引用并绑定到Model中的VO属性值,当特定的事件触发后,通过侦听事件去改变Model中的VO值,而页 面中绑定部分的值将跟随改变,从而实现多组件(页面)之间数据共享与同步。在讲到MVC模式时会以实例的方式详细分析这一用法。
元标签(metadata):在Flex中中经常会遇到类似[Bindable]这样以[]括起来形式的修饰符号,这类 符号被称之为元标签,元标签的作用主要是为编译器提供一些额外的信息,元标签本身不为被编译生成到SWF文件当中去,它只是用来告诉编译器如何来编程程 序,Flex SDK中为开发人员提供了大量的元标签,例如[Bindable]、[Event]、[Embed]均是很常用的元标签。在不同的应用场合,元标签可以加 在变量、类或方法的前面。
在类定义前添加[Bindable],绑定仅作用于类下面所有public的属性(所有这些属性均可作为源进行数据绑 定),而不会应用于类下面的private及protected属性。若要使非public属性也能作为数据绑定的源,则必须在属性定义前添加 [Bindable]元标签。注意,若在类定义前已经加了[Bindable],则不应在类的属性前再添加[Bindable]
[Bindable]的完整形式为[Bindable(event=”propertyChange”)],实际上我们简写为[Bindable] 默认指的是当“propertyChange”事件产生时会触发绑定功能应用,其中“propertyChange”事件的派发是由Flex编译为我们自 动生成的代码去完成的(在项目属性中的Flex编译参数中添加 -keep 参数),读者可尝试在我们前面的示例中将[Bindable]改为 [Bindable(event=”propertyChange”)],结果是一样的。
当然,我们也可以使用自定义事件去触发绑定,由于使用自定义事件,则自定义的派发由开发人员自己实现,在实际应用开发中也经常这样这样使用。
将Person类的改为:
1 2 3 4 5 6 7 |
package com.jexchen.model {
[Bindable(event="customEvent")]
public class Person {
public var firstName:String;
public var lastName:String;
}
}
|
相应主程序更改为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?xml version="1.0" encoding="utf-8"?>
<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="onCreationComplete()">
<fx:Script>
<![CDATA[
import com.jexchen.model.Person;
[Bindable(event="customEvent")]
public var person:Person = new Person();
private function onCreationComplete():void {
person.firstName = "Anthony";
person.lastName = "Lee";
dispatchEvent(new Event("customEvent"));
}
private function changeName():void {
person.firstName = "Bruce";
person.lastName = "Chan";
dispatchEvent(new Event("customEvent"));
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>
</s:layout>
<s:Label text="{person.firstName}" />
<s:Label text="{person.lastName}" />
<s:Button label="Change Name" click="changeName()" />
</s:Application>
|
由于我们更改了[Bindable]的默认方式,则在程序需手动派发相应的自定义事件才能触发绑定的实现(见上述代码所示)。
甚至可以在属性或方法前加多个事件绑定(),这样则可以让在不同的事件customEvent1和customEvent2派发时均可触发绑定功能。
package com.jexchen.model {
[Bindable(event="customEvent1")]
[Bindable(event="customEvent2")]
public class Person {
public var firstName:String;
public var lastName:String;
}
}
ChangeWatcher绑定实现
ChangeWatcher的使用也非常简单,例如,对person的firstName属性,使用ChangeWatcher的watch方法去 监测,一旦属性值发生变化,将会执行onWatcher回调方法,这里注意,默认情况下,person属性值改变会触发 “propertyChangeEvent”事件(Person类添加的是[Bindable]元标签),onWatcher参数需指明事件类型。
1 2 3 4 5 6 7 8 |
var watcher:ChangeWatcher = ChangeWatcher.watch(person, "firstName", onWatcher);
private function onWatcher(evt:PropertyChangeEvent):void {
firstNameId.text = evt.newValue.toString();
}
...
//当你要停止绑定时,手动调用
watcher.unwatch();
|
注意,ChangeWatcher.watcher()方法的返回值为ChangeWatcher实例,当我们需要停止绑定时,需手动调用unwatch()来解除绑定,以避免带来内存泄漏的问题。
双向绑定
前面我们实现的均是单一绑定功能,若希望在更改txtInputB组件text值的同时,txtInputA的text值也为同步变化,也即实现“双向绑定”的功能,我们可以为txtInputA的text属性再添加一次绑定即可,如下面代码所示。
<s:TextInput id="txtInputA" text="{txtInputB.text}"/>
<s:TextInput id="txtInputB" text="{txtInputA.text}"/>
在Flex4中,直接为我们提供了更为简捷的双向绑定功能,绑定也非常简单,以{}花括号和<Binding />标签两种方式如下:
//仅需在绑定符号{}外加上@符号即可
<s:TextInput id="txtInputB" text="@{txtInputA.text}"/>
//或者
//在<Binding/>标签中指定twoWay为true即
<fx:Binding source="txtInputA.text" destination="txtInputB.text" twoWay="true"/>
需要注意的是:
1. style或effect属性不能使用双向绑定
2. 当使用RemoteOject、WebService或HTTPServer时,作为通信传递的参数值不能使用双向绑定
相关推荐
《FLEX数据绑定专题》是一本深入探讨Adobe Flex中数据绑定技术的专业中文PDF文档。Flex是一种用于构建富互联网应用程序(RIA)的开放源码框架,它允许开发者创建交互性强、功能丰富的Web应用。数据绑定是Flex中一个...
Flex数据绑定是Adobe Flex框架中的核心特性之一,它允许开发者将UI组件的显示状态与应用程序的数据模型紧密关联,实现数据的动态更新。这份名为“FLEX数据绑定专题”的PDF文档,很可能深入探讨了这一主题,提供了...
Flex数据绑定是Adobe Flex开发中的核心特性之一,它允许开发者将UI组件的属性与应用程序的数据模型直接关联。在本示例中,我们关注的是如何在Flex中使用数据绑定技术来操作DataGrid组件,这是一个用于展示表格数据的...
数据绑定是Flex和Adobe AIR应用程序开发中的关键概念之一,其主要目的是实现不同对象之间的数据传输与同步更新。通过数据绑定,开发者能够轻松地在用户界面元素(如文本框、列表等)与后端数据模型之间建立连接。...
Flex数据绑定是软件开发中Adobe Flex或Adobe AIR应用程序的核心特性,它允许数据在不同对象之间自动同步。数据绑定简化了用户界面(UI)组件与数据源之间的交互,减少了手动更新的需要。然而,如果不理解其工作原理...
### Flex高级数据绑定实例——界面语言切换 #### 概述 在Flex开发中,实现界面的多语言切换是一项常见的需求。本示例通过一个具体的代码片段来展示如何使用Flex中的高级数据绑定技术来实现这一功能。该示例不仅...
5. Flex数据绑定 Flex支持强大的数据绑定机制,允许UI组件直接与应用程序的数据模型关联。当数据模型发生变化时,UI会自动更新,反之亦然,这大大简化了数据驱动的应用程序开发。 6. Flex与Flash Player Flex编译...
### Flex 4(Flash Builder 4)数据绑定教程(中文版) ...通过上述内容的学习,开发者可以更好地理解如何在Flex 4(Flash Builder 4)中实现高效的数据绑定,从而构建出更加完善和实用的应用程序。
在Flex开发中,动态绑定XML是一种常见的数据驱动技术,它允许开发者通过XML文件来存储和管理数据,并将这些数据实时地展示在用户界面中,如树形控件。本示例着重讲解如何利用动态绑定XML来实现Flex树控件的绑定,...
该文档主要介绍了一个基于MSTR ...这种数据绑定和交互设计在数据可视化和仪表盘应用中非常常见,能提供直观且灵活的数据探索体验。在实际的开发过程中,还需要考虑错误处理、用户界面优化以及性能优化等细节。
数据绑定是Flex的一个重要特性,它使得UI组件可以自动更新以反映数据源的变化。 5. **RemoteObject**:此组件允许直接调用服务器上的远程方法,就像调用本地方法一样,极大地简化了客户端和服务器间的通信。 在...
1. **数据绑定**:Flex中的数据绑定是连接UI组件和应用程序数据模型的关键机制。通过数据绑定,UI组件的属性可以自动反映模型数据的变化,反之亦然。例如,你可以将一个TextInput组件的text属性绑定到一个变量,当...
- **目标源关联**:验证器需要与一个包含待验证数据的目标源(如UI组件或数据模型)相绑定。 - **属性变化触发验证**:一旦目标源的指定属性发生变化,验证器就会被触发,执行验证逻辑。 - **事件机制**:验证完成后...
通过深入研究和实践这些示例,初学者可以逐步了解Flex3的各个方面,包括组件库的使用、数据绑定的机制、事件处理的原理以及如何与后端服务器进行数据交互。这将为他们后续的Flex开发工作打下坚实的基础。在学习过程...
Flex简介、Flex的安装和开发环境的建立、MXML 语法简介、使用容器控制界面布局、使用组件处理数据和交互、使用行为对象和动画效果、ActionScript 3.0编程知识、Flex的事件机制、数据绑定、组件的使用、Flex 2.0新...
在学习和使用Flex的过程中,经常会遇到一些常见问题,这些问题涉及到Flex的各个方面,包括版本管理、数据绑定、UI组件、以及与其他系统的集成等。 一、版本问题 在FlexPLM(Product Lifecycle Management,产品生命...
F1ex简介、Flex的安装和开发环境的建立、MXML语法简介、使用容器控制界面布局、使用组件处理数据和交互、使用行为对象和动画效果、ActionScript3.0编程知识、Flex的事件机制、数据绑定、组件的使用、F1ex2.0新特性...
数据绑定是Flex的核心特性之一,允许源属性的变化自动反映到目标属性上。Flex提供了三种绑定方式: 1. 在mxml中使用大括号`{}`直接绑定属性。 2. 使用`<fx:Binding>`标签在mxml中绑定属性。 3. 在as中使用`...
2. **数据绑定**:Flex中的数据绑定允许我们动态地将UI组件的属性与应用程序的数据模型关联起来。在这个例子中,我们将XML解析后的结果绑定到ComboBox的`dataProvider`属性上,这样ComboBox的下拉列表就会显示XML中...