开发者

Iterating a dataProvider in flex

I'm wondering... I want to iterate through a dataProvider, in a Component which is based on a DropDownList. First thing, that it didn't work (it compiled, but never iterated), was:

var o:Object;
for each (var o:Object in dataProvider)
{
}

I guess it didn't work because a IList doesn't provide Objects, or something someone would be able to explain easily.

I tried something that looks horrible from a efficiency perspective, nonetheless it works. This is it:

for (var i:int = 0; i < dataProvider.length; i++)
{
   o = dataProvider.getItemAt(i);
}

But it is so horrible that I felt tempted to ask here about another possible solution.

UPDATE:

I'll try to elaborate... I'm making (well, it is made already开发者_Go百科) a component that, being like a DropDownList, is bindable, not to an index (like selectedIndex="@{variable}"), but to a value of a variable inside of the ArrayCollection.

Say, you have a dataProvider with two objects: {a:'5', nmb:'five', blabla:'cinco'} and {a:'39', nmb:'thirty-nine', blabla:'treinta y nueve'}.

This component, if declared like this:

<com:ddListN idxName="a" selectedN="@{val}" labelField="nmb">

Does use val to set/get the DropDownList to the proper index, comparing the value with the variable defined in idxName.

Well, this is the entire code (is not that much):

<?xml version="1.0" encoding="utf-8"?>
<s:DropDownList xmlns:fx="http://ns.adobe.com/mxml/2009" 
                xmlns:s="library://ns.adobe.com/flex/spark" 
                xmlns:mx="library://ns.adobe.com/flex/mx"
                change="ch()">
    <fx:Declarations>
    </fx:Declarations>
    <fx:Script>
        <![CDATA[
            private var _selectedN:String;

            public var idxName:String = 'n';

            [Bindable(event="changeSelected")]
            public function get selectedN():String
            {
                return this.selectedItem[idxName];
            }

            public function set selectedN(v:String):void
            {
                var o:Object;
//              for each (var o:Object in dataProvider) @@
                for (var i:int = 0; i < this.dataProvider.length; i++)
                {
                    o = dataProvider.getItemAt(i);
                    if (o[idxName] == v)
                    {
                        this.selectedIndex = i;
                        _selectedN = v;
                        dispatchEvent(new Event("changeSelected"));
                        return; 
                    }

                }
                this.selectedItem = null; // no seleccionar nada (@@?)
                _selectedN = null;
                dispatchEvent(new Event("changeSelected"));
            }

            private function ch():void
            {
                _selectedN = this.selectedItem[idxName];
                dispatchEvent(new Event("changeSelected"));
            }
        ]]>
    </fx:Script>
</s:DropDownList>


Actually for each loops are a little bit slower than normal for loops. Take a look at the answer to For VS Foreach on Array performance.

To answer your question, why your for each loop doesn`t work. Unfortunatly this type of loop works only for certain types of classes. As far as I know those are:

  • Array
  • Vector
  • XML
  • XMLList
  • and classes that extend Proxy that implement the functions needed for for each loops. ListCollectionView and its subclasses ArrayCollection and XMLListCollection are the only ones I know of.

Collection classes like ArrayList do not work with for each loops since they are not native objects in Flash Player (like Array) and they don't extend the Proxy class.

So, the best thing you can do is to use simple for loops and those loops are even faster than the for each loops.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜