在 Flex 中迭代 dataProvider
我想知道...我想在基于 DropDownList 的组件中迭代 dataProvider。 首先,它不起作用(它编译了,但从未迭代):
var o:Object;
for each (var o:Object in dataProvider)
{
}
我猜它不起作用是因为 IList 不提供对象,或者有人能够轻松解释的东西。
我尝试了一些从效率角度来看看起来很糟糕的方法,但它确实有效。就是这样:
for (var i:int = 0; i < dataProvider.length; i++)
{
o = dataProvider.getItemAt(i);
}
但这太可怕了,我很想在这里询问另一种可能的解决方案。
更新:
我会尝试详细说明...我正在制作(嗯,它已经制作了)一个组件,就像 DropDownList 一样,是可绑定的,而不是索引(如 selectedIndex="@{variable}") ,而是 ArrayCollection 内部变量的值。
假设您有一个包含两个对象的 dataProvider: {a:'5', nmb:' Five', blabla:'cinco'}
和 {a:'39', nmb:'三十九',blabla:'treinta y nueve'}
。
该组件,如果这样声明:
<com:ddListN idxName="a" selectedN="@{val}" labelField="nmb">
是否使用 val
将 DropDownList 设置/获取到正确的索引,将该值与 idxName 中定义的变量进行比较。
好吧,这是整个代码(没那么多):
<?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>
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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
实际上,
for every
循环比普通for
循环慢一点。看看关于 VS Foreach on Array 性能的答案< /a>.要回答您的问题,为什么您的
for every
循环不起作用。不幸的是,这种类型的循环仅适用于某些类型的类。据我所知,这些是:Array
Vector
XML
XMLList
Proxy
的类code> 实现foreach
循环所需的函数。我只知道ListCollectionView
及其子类ArrayCollection
和XMLListCollection
。像
ArrayList
这样的集合类不能与foreach
循环一起使用,因为它们不是 Flash Player 中的本机对象(例如Array
),并且它们不扩展 Proxy 类。因此,您能做的最好的事情就是使用简单的
for
循环,这些循环甚至比foreach
循环更快。Actually
for each
loops are a little bit slower than normalfor
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 forfor each
loops.ListCollectionView
and its subclassesArrayCollection
andXMLListCollection
are the only ones I know of.Collection classes like
ArrayList
do not work withfor each
loops since they are not native objects in Flash Player (likeArray
) and they don't extend theProxy
class.So, the best thing you can do is to use simple
for
loops and those loops are even faster than thefor each
loops.