programming Flex2 学习笔记-第12章 使用数据(上)
时间:2007-11-26 来源:stone5
12章Working with Data
模型化数据和数据绑定
*henworkingwithdataYyougenerallywanttostoreitinsomesortofdatareposiw
torywithinmemory,…heserepositoriesareknownas datamodels,
使用数据模型作为一个从RPC获得的数据检索的仓库,存储将要被发送到服务端的数据。简单地收集表单输入的机制。
使用
<mx:Model id="example"/>
可在Model里放置数据的结构:
<mx:Model id="userData">
<user>
<email></email>
<phone></phone>
<address>
<city></city>
<state></state>
</address>
</user>
</mx:Model>
或者直接放置数据:
<mx:Model id="userData">
<user>
<email>[email protected]</email>
<phone>123 555-1212</phone>
<address>
<city>Exampleville</city>
<state>CA</state>
</address>
</user>
</mx:Model>
但一般把较多的数据这在一个文件中:
<mx:Model id="statesModel" source="states.xml" />
这个文件的数据是在编译时被载入,而不是运行时。它与在<Model>标签里直接嵌入数据是一样的,只不过这样更简洁。一旦编译成.swf文件之后,你就不用带上这个文件,因为数据已被编译进.swf文件。 <mx:Model>并不是有名叫Model一个ActionScript类与它对应,实际上它是创建了一个ObjectProxy类的实例,ObjectProxy对象是一个Object实例的封装,完全可以象Object实例一样去对待它,使用ObjectProxy主要的目的是可以数据绑定。
因为相当于在ActionScript中创建了一个对象,当然可以使用点语法来直接访问它的子节点对象。对象本身的ID与它的根节点是同义的。即访问其子节点对象时不用再加根对象的名字了。
当一个data model结构是由两个或更多的同名兄弟节点组成是,它们将被转换成一个数组。如statesModel.state将是一个数组,存储了statesModel对象的所有名为state的子对象。 一般<mx:Model>用于传统数据,如对象,字符串和数组。而想用XML格式数据时,使用<mx:XML>标签。
<mx:XML>有一个xmlns属性来指定这个XML的命名空间。
一个<mx:XML>标签,在ActionScript中默认是创建一个XML对象,此时它的format属性为缺省的e4x,如果设置为xml,将会创建一个flash.xml.XMLNode对象。
使用ActionScript类
虽然使用<mx:Model><mx:XML>简单省力,但在很多情况下并不是理想的方案。它们适用于简单,静态的数据。但对于复杂的,动态的,或者带有规则的数据,使用定制的ActionScript类是更好的方法。因为:
1)使用<mx:Model>和<mx:XML>你不能强制数据的类型,但AS能。
2)不能进行数据的测试/一致性检查等,但AS类的setter方法可以测试有效的值,对无效的值可以忽略,转换或是出错。
3)不能带上商务逻辑
4)不能使用优雅的设计模式。AS类可让整个应用都可存取的实例??? 写一个AS类作数据模型是简单的,只需定义一个类,为所有的属性定义公共的存取方法。所有setter和getter方法都是强类型的,有些Setter方法进行数据测试检查。
在包中定义类之后:
package com.oreilly.programmingflex.data {
public class User{
}
}
就可以在MXML中创建它的实例了,但得首先将包声明为命名空间: <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:data="com.oreilly.programmingflex.data.*" layout="absolute"> <data:User id="user" email="[email protected]" lastLogin="{new Date()}"
nameFirst="Abigail" nameLast="Smith" userType="1" /> </mx:Application>
若在AS中使用,你需要导入这个类,然后使用它:
import com.oreilly.programmingflex.data.User;
private var user:User; private function initializeHandler(event:Event):void {
user = new User();
user.email = "[email protected]";
// etc.
}
如果对基于自定义类的数据要执行数据绑定,在声明类时首先要使用[Bindable]元数据标签。在MXML内使用时,实例自动就允许了数据绑定的,在AS中使用时,也需在声明变量时使用[Bindable]元数据标签。
[Bindable]
public class User {
......
[Bindable]
private var user:User;
...... Data Binding数据绑定
关联数据
有三种方法激活数据绑定:
花括号{}
<mx:Binding>
BindingUtils
1)花括号用法:
关联到其它控件:
<mx:TextInput id="selectedLevel" text="{level.value}" />
也可在<mx:Model><mx:XML>中使用:
<mx:Model id="dataModel">
<userData>
<email>{email.text}</email>
<phone>{phone.text}</phone>
<city>{city.text}</city>
<state>{state.value}</state>
</userData>
</mx:Model>
也可在RemoteObject等组件的参数中直接使用:
<mx:RemoteObject id="example" destination="exampleService">
<mx:method name="saveContactInformation">
<mx:arguments>
<email>{dataModel.email}</email>
<phone>{dataModel.phone}</phone>
<city>{dataModel.city}</city>
<state>{dataModel.state}</state>
</mx:arguments>
</mx:method>
</mx:RemoteObject>
还可组成表达式,还可逐层使用(即B绑定A,C再绑定B)
<mx:TextArea width="200" height="200" text="{'Contact Information\nEmail: ' +
xmlData.@email + '\nPhone: ' + xmlData.@phone + '\nLocation: ' +
xmlData.@city + ', ' + xmlData.@state}" />
2)
<mx:Binding>必须在任何布局容器标签之外
如:<mx:Binding source="level.selectedItem.data" destination="selectedLevel.text" />
绑定到<mx:Model>中的dataModel.email到远程对象的参数中:
<mx:Binding source="dataModel.email" destination="example.saveContactInformation.arguments.email" />
可以将源或目标指定为XML数据的属性如:xmlData.@email
<mx:Binding>比花括号语法更麻烦点,功能一样,但是它更清晰地区分了用户布局和数据使用的代码。
3)使用mx.binding.utils.BindingUtils类可以在AS中动态的设置或改变数据绑定。
<mx:Button label="enable data binding" click="BindingUtils.bindProperty(textInput,'text',comboBox,'value')"/>
这个bindProperty()方法返回一个新的mx.binding.utils.ChangeWatcher对象的引用,可被用来取消数据绑定或改变源:
changeWatcher.unwatch();停止绑定
changeWatcher.getValue();获得绑定源的值
changeWatcher.reset(newSourceObject); 改变绑定的源对象
但是如果要改变绑定的源的属性,则必须停止然后重新绑定:
changeWatcher.unwatch();
changeWatcher = BindingUtils.bindProperty(newSource, newProperty, destination, destinationProperty);
例子代码节选:
_currentHost = _currentHost == level ? subLevel : level; 让currentHost在sublevel和level两个间切换。
_changeWatcher.reset(_currentHost);
selectedLevel.text = _changeWatcher.getValue().toString(); (注意,刚改变源并不能也直接触发目标数据的更新,须手动更新一次)
模型化数据和数据绑定
*henworkingwithdataYyougenerallywanttostoreitinsomesortofdatareposiw
torywithinmemory,…heserepositoriesareknownas datamodels,
使用数据模型作为一个从RPC获得的数据检索的仓库,存储将要被发送到服务端的数据。简单地收集表单输入的机制。
使用
<mx:Model id="example"/>
可在Model里放置数据的结构:
<mx:Model id="userData">
<user>
<email></email>
<phone></phone>
<address>
<city></city>
<state></state>
</address>
</user>
</mx:Model>
或者直接放置数据:
<mx:Model id="userData">
<user>
<email>[email protected]</email>
<phone>123 555-1212</phone>
<address>
<city>Exampleville</city>
<state>CA</state>
</address>
</user>
</mx:Model>
但一般把较多的数据这在一个文件中:
<mx:Model id="statesModel" source="states.xml" />
这个文件的数据是在编译时被载入,而不是运行时。它与在<Model>标签里直接嵌入数据是一样的,只不过这样更简洁。一旦编译成.swf文件之后,你就不用带上这个文件,因为数据已被编译进.swf文件。 <mx:Model>并不是有名叫Model一个ActionScript类与它对应,实际上它是创建了一个ObjectProxy类的实例,ObjectProxy对象是一个Object实例的封装,完全可以象Object实例一样去对待它,使用ObjectProxy主要的目的是可以数据绑定。
因为相当于在ActionScript中创建了一个对象,当然可以使用点语法来直接访问它的子节点对象。对象本身的ID与它的根节点是同义的。即访问其子节点对象时不用再加根对象的名字了。
当一个data model结构是由两个或更多的同名兄弟节点组成是,它们将被转换成一个数组。如statesModel.state将是一个数组,存储了statesModel对象的所有名为state的子对象。 一般<mx:Model>用于传统数据,如对象,字符串和数组。而想用XML格式数据时,使用<mx:XML>标签。
<mx:XML>有一个xmlns属性来指定这个XML的命名空间。
一个<mx:XML>标签,在ActionScript中默认是创建一个XML对象,此时它的format属性为缺省的e4x,如果设置为xml,将会创建一个flash.xml.XMLNode对象。
使用ActionScript类
虽然使用<mx:Model><mx:XML>简单省力,但在很多情况下并不是理想的方案。它们适用于简单,静态的数据。但对于复杂的,动态的,或者带有规则的数据,使用定制的ActionScript类是更好的方法。因为:
1)使用<mx:Model>和<mx:XML>你不能强制数据的类型,但AS能。
2)不能进行数据的测试/一致性检查等,但AS类的setter方法可以测试有效的值,对无效的值可以忽略,转换或是出错。
3)不能带上商务逻辑
4)不能使用优雅的设计模式。AS类可让整个应用都可存取的实例??? 写一个AS类作数据模型是简单的,只需定义一个类,为所有的属性定义公共的存取方法。所有setter和getter方法都是强类型的,有些Setter方法进行数据测试检查。
在包中定义类之后:
package com.oreilly.programmingflex.data {
public class User{
}
}
就可以在MXML中创建它的实例了,但得首先将包声明为命名空间: <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:data="com.oreilly.programmingflex.data.*" layout="absolute"> <data:User id="user" email="[email protected]" lastLogin="{new Date()}"
nameFirst="Abigail" nameLast="Smith" userType="1" /> </mx:Application>
若在AS中使用,你需要导入这个类,然后使用它:
import com.oreilly.programmingflex.data.User;
private var user:User; private function initializeHandler(event:Event):void {
user = new User();
user.email = "[email protected]";
// etc.
}
如果对基于自定义类的数据要执行数据绑定,在声明类时首先要使用[Bindable]元数据标签。在MXML内使用时,实例自动就允许了数据绑定的,在AS中使用时,也需在声明变量时使用[Bindable]元数据标签。
[Bindable]
public class User {
......
[Bindable]
private var user:User;
...... Data Binding数据绑定
关联数据
有三种方法激活数据绑定:
花括号{}
<mx:Binding>
BindingUtils
1)花括号用法:
关联到其它控件:
<mx:TextInput id="selectedLevel" text="{level.value}" />
也可在<mx:Model><mx:XML>中使用:
<mx:Model id="dataModel">
<userData>
<email>{email.text}</email>
<phone>{phone.text}</phone>
<city>{city.text}</city>
<state>{state.value}</state>
</userData>
</mx:Model>
也可在RemoteObject等组件的参数中直接使用:
<mx:RemoteObject id="example" destination="exampleService">
<mx:method name="saveContactInformation">
<mx:arguments>
<email>{dataModel.email}</email>
<phone>{dataModel.phone}</phone>
<city>{dataModel.city}</city>
<state>{dataModel.state}</state>
</mx:arguments>
</mx:method>
</mx:RemoteObject>
还可组成表达式,还可逐层使用(即B绑定A,C再绑定B)
<mx:TextArea width="200" height="200" text="{'Contact Information\nEmail: ' +
xmlData.@email + '\nPhone: ' + xmlData.@phone + '\nLocation: ' +
xmlData.@city + ', ' + xmlData.@state}" />
2)
<mx:Binding>必须在任何布局容器标签之外
如:<mx:Binding source="level.selectedItem.data" destination="selectedLevel.text" />
绑定到<mx:Model>中的dataModel.email到远程对象的参数中:
<mx:Binding source="dataModel.email" destination="example.saveContactInformation.arguments.email" />
可以将源或目标指定为XML数据的属性如:xmlData.@email
<mx:Binding>比花括号语法更麻烦点,功能一样,但是它更清晰地区分了用户布局和数据使用的代码。
3)使用mx.binding.utils.BindingUtils类可以在AS中动态的设置或改变数据绑定。
<mx:Button label="enable data binding" click="BindingUtils.bindProperty(textInput,'text',comboBox,'value')"/>
这个bindProperty()方法返回一个新的mx.binding.utils.ChangeWatcher对象的引用,可被用来取消数据绑定或改变源:
changeWatcher.unwatch();停止绑定
changeWatcher.getValue();获得绑定源的值
changeWatcher.reset(newSourceObject); 改变绑定的源对象
但是如果要改变绑定的源的属性,则必须停止然后重新绑定:
changeWatcher.unwatch();
changeWatcher = BindingUtils.bindProperty(newSource, newProperty, destination, destinationProperty);
例子代码节选:
_currentHost = _currentHost == level ? subLevel : level; 让currentHost在sublevel和level两个间切换。
_changeWatcher.reset(_currentHost);
selectedLevel.text = _changeWatcher.getValue().toString(); (注意,刚改变源并不能也直接触发目标数据的更新,须手动更新一次)
相关阅读 更多 +