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

来源:互联网 发布:淘宝投诉卖家电话 编辑:程序博客网 时间:2024/04/30 02:40

一些Flex框架组件,包括所有基于list的控件,表现来自data provider的数据。data provider 就是一个包含控件需要的数据的对象。例如,一个Tree控件的数据提供器决定了树的结构并且相关的数据都被赋值到对应的节点中,一个ComboBox控件的数据提供器决定了下拉列表中的元素。许多标准控件,包括ColorPicker和MenuBar控件也从数据提供器中取得数据。显示应用程序数据的控件被称为数据提供器控件。


本快速入门描述几种使用数据提供器的途径:

用数组作为数据提供器

限制性数组和对象作为数据提供器

使用集合作为数据提供器(通过使用MXML)

使用集合作为数据提供器(通过使用ActionScript)

使用外部加载的数据作为数据提供器

修改数据提供器的数据,并监听这个事件

用数组作为数据提供器
最简单的数据提供器就是一个字符串或对象的数组。下边的例子使用字符串的数组作为数据提供器,创建一个静态的ComboBox控件。

例子

<?xml version="1.0" encoding="utf-8"?>
<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>
 

本文来自:http://www.airia.cn/FLEX_Directory/using_data_providers/

 

原创粉丝点击