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>
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With