Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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) 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>
like image 320
huff Avatar asked Feb 26 '23 16:02

huff


1 Answers

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.

like image 197
Gerhard Schlager Avatar answered Mar 08 '23 04:03

Gerhard Schlager