`
strugglesMen
  • 浏览: 111951 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

Flex数据绑定基础介绍

阅读更多

相信只要开发过Flex应用程序的读者都已经使用过数据绑定(Data Binding),数据绑定是Flex非常重要的特性之一,它就像一种魔法一样,能快速让你将应用程序中两个不同的部份通过数据绑定联系起来,大大提高了 开发的效率,这也是让Flex如此流行的特性之一。大多时候我们并不需要了解数据绑定背后的机制,然而,随着在Flex应用程序规模不断增大,数据绑定特 性也被开发人员使用得越来越多,其带来的问题也逐渐显现出来,正因为它像魔法一样,使用起来非常简单,因而很多开发人员并未去深入了解数据绑定背后的工作 机制,致使在应用中使用不合理,这样不仅会给应用程序带来性能上的问题,也会使得程序难以维护,甚至可能带来不可预料的Bug,很难跟踪处理。

本节首先会简要介绍数据绑定的基本概念及其常见应用,然后带领大家深入“幕后”,剖析”魔法”倒底是怎样产生的,最后在最佳实践部分给大家介绍一下在实际运用数据绑定时常犯的错误及纠正方案。

 Flex数据绑定简介与常见应用

数据绑定是这样一种特性,它能方便的让一个对象的数据自动反映到另外一对象的数据上,通常需要我们提供“数据源属性”和”数据目标属性“,有了源与 目标,当我们使用数据绑定特性时,它会自动帮我们把”数据源属性“的值拷贝到“数据目标属性“值中去。本质上来说,Flex绑定功能的实现也是对事件机制 的运用体现,在后序文章:数据绑定背后的故事部分会详细阐述这一点。

Flex为我们提供了多种使用数据绑定的方式,归纳起来通常有以下几种:

  1. {}绑定实现
  2. <Binding />标记绑定实现
  3. 应用BindingUtil类绑定实现
  4. ChangeWacher绑定实现
  5. [Bindable]元标签绑定实现
  6. 双向绑定

下面以一非常简单的程序为例,以不同的数据绑定方式来实现同样的绑定功能,以便读者能对比不同数据绑定实现方式之间的不同之处。

最终程序运行效果如图所示,当我们在上面的文字输入框输入文字时,借助绑定的功能,下面的文字输入框将同步显示在上面输入框输入的内容:

{}数据绑定运行效果

{}绑定实现

完整程序源码如下:

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类进行绑定又包括两种方式:

  1. 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()方法参数的顺序,需要绑定的目标对象及属性在前,而源对象及属性在后。

  1. 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时,作为通信传递的参数值不能使用双向绑定

 

 

 

http://www.riameeting.com/node/986

分享到:
评论

相关推荐

    FLEX简单的入门快速总结

    FLEX 数据绑定 Flex HTTPservice使用 Flex 创建自定义事件。 其它入门基础等。

    Flex基础教程实例源码

    flex基础教程实例源码 Array、数据绑定、事件机制等16个实例

    Flex 3 基础教程4)

    Flex 3 基础教程(4) —Flex 3 数据绑定

    FLEX企业应用开发实战.part1

    第2章 Flex企业应用开发基础  2.1 MXML语言  2.1.1 用MXML表示ActionScript对象  2.1.2 查看由MXML文件所翻译的ActionScript代码  2.1.3 IMXMLObject接口  2.2 客户端保持状态  2.3 客户端MVC  2.4 ...

    FLEX企业应用开发实战.part2

    第2章 Flex企业应用开发基础  2.1 MXML语言  2.1.1 用MXML表示ActionScript对象  2.1.2 查看由MXML文件所翻译的ActionScript代码  2.1.3 IMXMLObject接口  2.2 客户端保持状态  2.3 客户端MVC  2.4 ...

    FLEX从入门到精通.pdf

     6.3.3 使用数据绑定  6.3.4 使用触发器和特效  6.3.5 编译应用程序  6.4 创建ActionScript应用程序  6.4.1 创建ActionScript项目  6.4.2 比较文件大小  6.5 非正式的SWF元数据标记  6.6 本章小结 ...

    Flex企业应用开发实战源代码

    首先介绍了Flex/Flash的工作机理和利用Flex开发企业级应用必须掌握的基础知识和核心元素;接着剖析了Flex与Java的通信机制,以及Flex企业应用的客户端架构和服务器端架构;再接着详细讲解了BlazeDS框架的使用方法和...

    自创Flex入门教程

    刚刚接触 Flex 有一个星期了,有了点感觉,但一直在琢磨 Flex 和后台的数据通信问题,一个偶然想起了 Apache 的 XMLBean,所以就做了个小例子。例子比较细,每个步骤都 有有截图,请耐心看完,基本上是针对无基础的...

    FLEX入门及集成其他框架教程

    FLEX,是一种基于标准变成模型的RIA开发产品集,最开始是由...MXML:一种XML标识语言,用来进行组件布局,数据绑定等,和HTML语言有点类似。 ActionScript:刚开始时是FLASH的脚本语言,到了3.0,已经完全面向对象了

    flex3的cookbook书籍完整版dpf(包含目录)

    对添加到State中的Object进行数据绑定 11.10节. 在State Changes事件中添加和删除事件监听器 11.11节. 添加视图States到Flash组件 11.12节. 处理StateChange 事件 11.13节. 动态生成States和Transitions 11.14节. ...

    Flex_4:开发RIA_应用程序.pdf

    了解Flex 4 基础知识 了解Adobe Flex 命名空间 ............................................................................................................................. 32 了解命名空间如何转换为...

    Ranorex用户指南

    绑定变量和测试数据 绑定变量和参数 Invoking 动作: 选择 执行数据驱动测试 [课程4:Ranorex测试套件] 测试套件编辑器 模块组编辑器 一个测试套件和它的测试用例的通用结构 运行一个测试套件 不使用Ranorex ...

    电商类小程序实战教程 Vol.2:列表加载

    在上一期文章中,我们以爱范儿旗下的玩物志电商小程序作为 Demo,介绍了首页 banner 部分的开发,以及微信小程序内置组件、数据绑定和发送请求 API 的用法。 本期,知晓程序依然以玩物志电商小程序为基础,为大家...

    Flash ActionScript 3.0高级动画教程

    加载或绑定shader 使用shader作为绘制填充 访问shader元数据 设置shader参数值 转换shader填充 用shader填充制作动画 指定shader的输入图片 使用shader作为滤镜 使用shader作为混合模式 总结 第十章 补间 引擎 Flash...

    asp.net知识库

    利用反射实现ASP.NET控件和数据实体之间的双向绑定,并且在客户端自动验证输入的内容是否合法 asp.net报表解决方法 SQLDMO类的使用 SQL过程自动C#封装,支持从表到基本存储过程生成 使用SQLDMO控制 SQL Server 使用SQL...

    ActionScript开发技术大全

    第29章AIR部分特性介绍 598 29.1AIR本地窗口 598 29.1.1创建与关闭本地窗口 598 29.1.2添加窗体内容 600 29.1.3位置与尺寸 600 29.1.4窗口层叠控制 602 29.1.5本地窗口控制示例 602 29.2访问文件系统 612 29.2.1目录...

    gsoap 2.8 (SOAP/XML 关于C/C++ 语言的自动化实现工具内附 CSharp webservice例子,及GSOAP client和server例子)

     gSOAP2.0及之后的版本是在1.x版基础上重写的。gSOAP2.0之后的版本是线程安全的,但之前版本不是。gSOAP2.x版本中的主要文件已经重新  命名,以便与1.x版区分。  gSOAP 1.X gSOAP 2.X  soapcpp soapcpp2  ...

    Maven权威指南 很精典的学习教程,比ANT更好用

    1. 介绍 Apache Maven 1.1. Maven... 它是什么? 1.2. 约定优于配置(Convention Over Configuration) 1.3. 一个一般的接口 1.4. 基于Maven插件的全局性重用 1.5. 一个“项目”的概念模型 1.6. Maven是Ant的...

Global site tag (gtag.js) - Google Analytics