首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 媒体动画 > flex >

Flex 三快速入门(17): 构建高级用户界面 使用数据提供程序

2012-10-26 
Flex 3快速入门(17): 构建高级用户界面 使用数据提供程序?mx:Application ??? xmlns:mxhttp://www.adob

Flex 3快速入门(17): 构建高级用户界面 使用数据提供程序

?

<mx:Application
??? xmlns:mx="http://www.adobe.com/2006/mxml"
??? viewSourceURL="src/DataProviderArray/index.html"

??? width="150" height="140"
>
??? <mx:Script>
??????? <![CDATA[

??????????? [Bindable]
??????????? public var myArray:Array = ["AL", "AK", "AR"];
??????? ]]>

??? </mx:Script>
??? <mx:ComboBox id="statesCombo" dataProvider="{myArray}"/>
</mx:Application>

限制性数组和对象作为数据提供器
使用原始数据对象,比如数组或对象,有一些局限性:

如果数据改变,那么原始数据对象的功能就不够充分了。因为控件不会从数据对象那里收到任何改变显示列表的通知。所以,在控件被重画以前,控件不会更新列表。因为重画会让程序中改变的数据被重新分配给控件。

?

原始数据对象没有提供高级工具,比如访问,保存或过滤数据。比如,如果使用Array作为作为数据提供器,就只能使用Adobe? Flash? Array 的方法操作数据。


注意:这个局限是在Flex2中新产生的。在Flex 1.5或更早的版本中,当数组作为数据提供器的死后,Flex习惯于把事件分发机制与访问、保存和过滤方法混合在一起。这一点在把应用程序从Flex 1.5向2.0或30上迁移时是必须紧记的。在下一节中,我们使用新的Collection类克服这个局限。

在下边的例子中,使用数组作为List控件数据提供器,显示3个博客的名字。当用户按下“Add A Blogger”按钮,Flex增加第四个博客名字到数组中。然而被增加的名字没有马上显示在List控件中,除非你按“Reassign Data Provider”按钮,重新指定这个控件的dateProvider属性。

例子


<?xml version="1.0" encoding="utf-8"?>

<mx:Application
??? xmlns:mx="http://www.adobe.com/2006/mxml"
??? viewSourceURL="src/DataProviderArrayLimitations/index.html"
??? width="350"??? height="220"
>

??? <mx:Script>
??????? <![CDATA[
??????????? [Bindable]
??????????? public var bloggersArray:Array =
??????????????? ["Andy Budd", "Grant Skinner", "Paul Booth"];
??????? ]]>

??? </mx:Script>
??? <mx:Panel title="Bloggers we love!" width="100%">
??????? <mx:List
??????????? id="bloggersList" width="100%" rowCount="4"
??????????? dataProvider="{bloggersArray}"

??????? />????????
??? </mx:Panel>
??? <mx:ApplicationControlBar>
??????? <mx:Button
??????????? label="Add a blogger!"
??????????? click="bloggersArray[3]=&apos;Pete-Barr Watson&apos;;"

??????? />
??????? <mx:Button
??????????? label="Reassign data provider."
??????????? click="bloggersList.dataProvider=bloggersArray"
??????? />???????????????
??? </mx:ApplicationControlBar>

</mx:Application>

使用集合作为数据提供器(通过使用MXML)
Flex 提供一个集合机制来确保数据同步,并且提供简单先进的数据访问和操作方式。


你能够使用一个实现了ICollectionView 或者 IList 接口 的对象直接放在MXML控件标签中,作为数据提供器。MXML和ActionScript都能够做到。


下边的例子展示了使用MXML如何创建一个ArrayCollection并把它作为List组件的数据提供器。

<?xml version="1.0" encoding="utf-8"?>

<mx:Application
??? xmlns:mx="http://www.adobe.com/2006/mxml"
??? viewSourceURL="src/DataProviderArrayLimitations/index.html"
??? width="350"??? height="220"
>

??? <mx:Panel title="Bloggers we love!" width="100%">

??????? <mx:List id="bloggersList" width="100%" rowCount="4">

??????????? <mx:dataProvider>
??????????????? <mx:ArrayCollection id="bloggers">
??????????????????? <mx:Object label="Andy Budd" url="http://andybudd.com"/>

??????????????????? <mx:Object label="Grant Skinner" url="http://gskinner.com"/>
??????????????????? <mx:Object label="Paul Booth" url="http://paulbooth.com"/>

??????????????? </mx:ArrayCollection>
??????????? </mx:dataProvider>
??????? </mx:List>???????

??????? <mx:ControlBar horizontalAlign="center">
??????????? <mx:Button
??????????????? label="Add a blogger!"
??????????????? click="bloggers.addItem({label:'Pete-Barr Watson', url:'http://petebarrwatson.com/'});"

??????????? />
??????? </mx:ControlBar>

??? </mx:Panel>
</mx:Application>


使用集合作为数据提供器(通过使用ActionScript)
下边的例子展示了如何通过ActionScript创建一个ArrayCollection并且把它为List组件的数据提供者。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
??? xmlns:mx="http://www.adobe.com/2006/mxml"
??? viewSourceURL="src/DataProviderArrayLimitations/index.html"

??? width="350"??? height="220"
??? creationComplete="creationCompleteHandler(event);"
>
??? <mx:Script>

??????? <![CDATA[
??????????? import mx.collections.ArrayCollection;
??????????? import mx.events.FlexEvent;
???????????
??????????? private var bloggersArray:Array =
??????????? [

??????????????? {label: "Andy Budd", url:"http://andybudd.com"},
??????????????? {label: "Grant Skinner", url:"http://gskinner.com"},
??????????????? {label: "Paul Booth", url:"http://paulbooth.com"}

??????????? ];
???????????
??????????? [Bindable]
??????????? private var bloggersCol:ArrayCollection;
???????????
??????????? private function creationCompleteHandler(event:FlexEvent):void

??????????? {
??????????????? bloggersCol = new ArrayCollection (bloggersArray);???
??????????? }
??????? ]]>

??? </mx:Script>
??? <mx:Panel title="Bloggers we love!" width="100%">

??????? <mx:List
??????????? id="bloggersList" width="100%" rowCount="4"

??????????? dataProvider="{bloggersCol}"
??????? />

??????? <mx:ControlBar horizontalAlign="center">
??????????? <mx:Button
??????????????? label="Add a blogger!"
??????????????? click="bloggersCol.addItem({label:'Pete-Barr Watson', url:'http://petebarrwatson.com/'});"

??????????? />
??????? </mx:ControlBar>

??? </mx:Panel>
</mx:Application>


提示:如果你知道一个控件提供器一直代表特定集合类,你可以使用直接使用这个类。比如在前边使用ArrayCollection的例子。然而,如果你的控件必须能够处理不同的数据类型,比如ArrayCollection 或者 XMLListCollection ,你应该绑定数据提供器到一个ICollectionView 类型的属性中。就像下边的代码一样。(译者:说实话我对这段话也没理解。暂时直译过来。)

[Bindable]
private var bloggersCol:ICollectionView;

使用外部加载的数据作为数据提供器
在富因特网应用程序(RIA)中,从外部载入并显示数据是一个普遍的特性。HTTPService控件是从外部载入数据的机制之一。为了把XML数据通过HTTPService控件读入到Flex数据提供器控件中,需要遍历XML节点,保存到ArrayCollection 中,并绑定到控件的dataProvider属性中

提示:确保你发布数据文件到正确的位置。指定给HTTPService 控件的URL是包含Flex应用程序的HTML文件的相对位置,不是Flex应用程序生成的SWF文件的相对位置。

另外,当为HTTPService控件的URL时,应该一直使用正斜线。当离线测试Flex应用程序的时候,反斜线也可以工作。但是挡在服务器上的时候,可能因为被URL编码%5C而导致错误。


使用HTTPService控件的lastResult属性可以绑定到数据提供器的控件上。然而,下边例子展示了稍微更详细的方法使代码更容易维护和扩展。


下边例子使用HTTPService控件读入一个XML文件,并把读入的数据作为List控件的数据提供器。

例子

Model (bloggers.xml)

<bloggers>
??? <blogger>
??????? <name>Andy Budd</name>
??????? <url>http://andybudd.com</url>
??? </blogger>

??? <blogger>
??????? <name>Grant Skinner</name>
??????? <url>http://gskinner.com</url>
??? </blogger>
??? <blogger>

??????? <name>Paul Booth</name>
??????? <url>http://paulbooth.com</url>
??? </blogger>???
</bloggers>


Main application file


<?xml version="1.0" encoding="utf-8"?>
<mx:Application
??? xmlns:mx="http://www.adobe.com/2006/mxml"
??? viewSourceURL="src/DataProviderExternal/index.html"

??? width="350"??? height="220"
??? creationComplete="bs.send();"
>
??? <mx:Script>

??????? <![CDATA[
??????????? import mx.managers.CursorManager;
??????????? import mx.rpc.events.InvokeEvent;
??????????? import mx.controls.Alert;
??????????? import mx.rpc.events.FaultEvent;
??????????? import mx.rpc.events.ResultEvent;
??????????? import mx.collections.ArrayCollection;
???????????
??????????? [Bindable]

??????????? private var bloggersCol:ArrayCollection;
???????????
??????????? // Gets called when HTTPService is invoked to
??????????? // request the XML.
??????????? private function bsInvokeHandler(event:InvokeEvent):void

??????????? {
??????????????? // Display the busy cursor
??????????????? CursorManager.setBusyCursor();
??????????? }
???????????
??????????? // Gets called when the XML is successfully loaded.
??????????? private function bsResultHandler(event:ResultEvent):void

??????????? {
??????????????? // Save a reference to the list of bloggers
??????????????? bloggersCol = event.result.bloggers.blogger;
???????????????
??????????????? // Hide the busy cursor
??????????????? CursorManager.removeBusyCursor();
??????????? }

???????????
??????????? private function bsFaultHandler(event:FaultEvent):void
??????????? {

??????????????? // There was an error in loading the XML
??????????????? Alert.show (event.fault.message);???
???????????????
??????????????? // Hide the busy cursor
??????????????? CursorManager.removeBusyCursor();
??????????? }
??????? ]]>

??? </mx:Script>
???
??? <!-- Service to load in XML -->
??? <mx:HTTPService
??????? id="bs"
??????? url="data/bloggers.xml"

??????? invoke="bsInvokeHandler(event);"
??????? result="bsResultHandler(event);"
??????? fault="bsFaultHandler(event);"

??? />
???
??? <mx:Panel title="Bloggers we love!" width="100%">

??????? <mx:List
??????????? id="bloggersList" width="100%" rowCount="4"

??????????? dataProvider="{bloggersCol}"
??????????? labelField="name"
??????? />

??????? <mx:ControlBar horizontalAlign="center">

??????????? <mx:Button
??????????????? label="Add a blogger!"
??????????????? click="bloggersCol.addItem({name:'Pete-Barr Watson', url:'http://petebarrwatson.com/'});"

??????????? />
??????? </mx:ControlBar>

??? </mx:Panel>
</mx:Application>

修改数据提供器的数据,并监听这个事件
在Flex中,Collection类实现了IList接口,这个接口提供一些方法(adding,removing,updating)来修改集合中的元素。可以使用IList接口的方法和属性在ArrayCollection类, XMLList类,和标准Flex控件的dataProvider 属性上。可以使用IList的addItem(), removeItem(), 和setItemAt() 方法分别增加,删除和更新元素数据。addItemAt() and removeItemAt() methods, 和the setItemAt()方法提供第二个参数,下标位置,来指定要在集合中影响的位置。IList接口的length属性返回集合中元素的数量。


Flex的集合机制也包括描述数据改变的事件。实现了IList 或者 ICollectionView 接口的类,无论何时数据发生改变,都分发CollectionEvent类事件所有集合时间都包含类型属性值CollectionEvent.COLLECTION_CHANGE。

注意:你也可以使用ICollectionView接口来保存和过滤数据。更多的信息请查看Flex3开发手册的Using ICollectionView interface methods and properties章节

CollectionEvent对象有kind属性标志着集合被改变的方式。通过kind属性与CollectionEventKind的常量的对比,你可以测试集合所发生的改变。主要的常量包括ADD,REMOVE和 UPDATE。


CollectionEvent对象包含一个items属性这个属性是一个对象的数组,这个数组的类型依赖于对象分发的事件的类型。对于ADD和REMOVE时间,这个数组包含added和removed数组。对于UPDATE事件,这个items属性包含PropertyChangeEvent事件对象数组。这些对象的属性显示出改变的类型和属性改变之前和之后的值。例如,PropertyChangeEvent类的kind属性显示出属性被改变的方式;你可以测试改变的类型通过把kind属性与PropertyChangeEventKind的常量UPDATE或DELETE.


下边的例子监听DataGrid的改变事件,来创建一个概览——详细关系。在这个关系中,选择一个DataGrid中的一行后,数据会显示在几个form控件中,然后你就可以编辑数据了。(使用概览——详细关系可以使DataGrid控件具有可编辑功能)。通过IList接口的addItem(), removeItem(), and setItemAt()方法,可以对DataGrid中的数据增加,删除,修改。这个例子也监听ArrayCollection上的collectionChange时间保持对数据增删改的日志记录。

例子


<?xml version="1.0" encoding="utf-8"?>
<mx:Application
??? xmlns:mx="http://www.adobe.com/2006/mxml"
???? viewSourceURL="src/DataProviderModifyingAndEvents/index.html"
??? width="525" height="530"

>
??? <mx:Script>
??????? <![CDATA[
???????????
??????????? import mx.events.*;
??????????? import mx.collections.*;
???????????
??????????? // Add event information to a log (displayed in the TextArea).

??????????? public function collectionEventHandler(event:CollectionEvent):void
??????????? {
??????????????? switch(event.kind)
??????????????? {

??????????????????? case CollectionEventKind.ADD:
??????????????????????? addLog("Item "+ event.location + " added");
??????????????????????? break;
??????????????????? case CollectionEventKind.REMOVE:

??????????????????????? addLog("Item "+ event.location + " removed");
??????????????????????? break;
??????????????????? case CollectionEventKind.REPLACE:

??????????????????????? addLog("Item "+ event.location + " Replaced");
??????????????????????? break;
??????????????????? case CollectionEventKind.UPDATE:

??????????????????????? addLog("Item updated");
??????????????????????? break;
??????????????? }
??????????? }
??????????? // Helper function for adding information to the log.
??????????? public function addLog(str:String):void
??????????? {

??????????????? log.text += str + "\n";
??????????? }
???????????
??????????? // Add a person to the ArrayCollection.
??????????? public function addPerson():void
??????????? {

??????????????? ac.addItem({first:firstInput.text, last:lastInput.text,
??????????????????????? email:emailInput.text});
??????????????? clearInputs();
??????????? }
???????????
??????????? // Remove a person from the ArrayCollection.

??????????? public function removePerson():void
??????????? {
??????????????? // Make sure an item is selected.
??????????????? if (dg.selectedIndex >= 0)
??????????????? {

??????????????????? ac.removeItemAt(dg.selectedIndex);
??????????????? }
??????????? }
???????????
??????????? // Update an existing person in the ArrayCollection.
??????????? public function updatePerson():void
??????????? {

??????????????? // Make sure an item is selected.
??????????????? if (dg.selectedItem !== null)
??????????????? {
??????????????????? ac.setItemAt({first:firstInput.text, last:lastInput.text,
??????????????????????? email:emailInput.text}, dg.selectedIndex);
??????????????? }

??????????? }
???????????
??????????? // The change event listener for the DataGrid.
??????????? // Clears the text input controls and updates them with the contents
??????????? // of the selected item.
??????????? public function dgChangeHandler():void
??????????? {

??????????????? clearInputs();
??????????????? firstInput.text = dg.selectedItem.first;
??????????????? lastInput.text = dg.selectedItem.last;
??????????????? emailInput.text = dg.selectedItem.email;
??????????? }
???????????
??????????? // Clear the text from the input controls.

??????????? public function clearInputs():void
??????????? {
??????????????? firstInput.text = "";
??????????????? lastInput.text = "";
??????????????? emailInput.text = "";
??????????? }

???????
??????? ]]>
??? </mx:Script>
???
??? <!-- The ArrayCollection used by the DataGrid and ComboBox. -->
??? <mx:ArrayCollection id="ac"

??????????? collectionChange="collectionEventHandler(event)">
??????? <mx:source>
??????????? <mx:Object first="Matt" last="Matthews" email="matt@myco.com"/>

??????????? <mx:Object first="Sue" last="Sanderson" email="sue@myco.com"/>
??????????? <mx:Object first="Harry" last="Harrison" email="harry@myco.com"/>

??????? </mx:source>
??? </mx:ArrayCollection>

??? <mx:Panel title="Master-Detail View" width="100%">
???????
??????? <mx:DataGrid width="100%" id="dg" dataProvider="{ac}"

??????????????? change="dgChangeHandler()">
??????????? <mx:columns>
??????????????? <mx:DataGridColumn dataField="first" headerText="First Name"/>

??????????????? <mx:DataGridColumn dataField="last" headerText="Last Name"/>
??????????????? <mx:DataGridColumn dataField="email" headerText="Email"/>
??????????? </mx:columns>

??????? </mx:DataGrid>
???????
??????? <!-- Form for data to add or change in the ArrayCollection. -->
??????? <mx:Form label="test" width="100%">

?????????? <mx:FormItem label="First Name" width="100%">
??????????????? <mx:TextInput id="firstInput" width="100%"/>

?????????? </mx:FormItem>
?????????? <mx:FormItem label="Last Name" width="100%">
??????????????? <mx:TextInput id="lastInput" width="100%"/>

?????????? </mx:FormItem>
?????????? <mx:FormItem label="Email" width="100%">
??????????????? <mx:TextInput id="emailInput" width="100%"/>

?????????? </mx:FormItem>
??????? </mx:Form>
???
??????? <mx:ControlBar horizontalAlign="center">
??????????? <!-- Buttons to initiate operations on the collection. -->

??????????? <mx:Button label="Add New" click="addPerson()"/>
??????????? <mx:Button label="Update Selected" click="updatePerson()"/>

??????????? <mx:Button label="Remove Selected" click="removePerson()"/>
??????????? <!-- Clear the text input fields. -->

??????????? <mx:Button label="Clear" click="clearInputs()"/>
??????? </mx:ControlBar>

??? </mx:Panel>

??? <!-- The application displays event information here -->
??? <mx:Panel title="Change log" width="100%" height="125">???????
??????? <mx:TextArea id="log" width="100%" height="100%"/>

??? </mx:Panel>??

</mx:Application>

结果

??

热点排行