2010-12-01 5 views
4

私は疑問に思っています... DropDownListに基づくComponentでdataProviderを反復処理したいと思います。それが機能しなかったことを まず最初に、(それがコンパイルされますが、繰り返されません)、したflexで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); 
} 

しかし、私は別の可能な解決策についてはこちらを尋ねるように誘惑を感じたほど恐ろしいです:これはそれです。

UPDATE:

私は詳しく説明しようとするでしょう...私は、(まあ、それはすでに行われている)DropDownListのようなもの、部品を作っていないインデックスに、バインド可能です(selectedIndexのような= "@ {変数}")、ArrayCollection内部の変数の値に設定します。

2つのオブジェクト({a:'5', nmb:'five', blabla:'cinco'}および{a:'39', nmb:'thirty-nine', blabla:'treinta y nueve'})を持つdataProviderがあるとします。このように宣言した場合

このコンポーネント、:

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

idxNameで定義された変数と値を比較し、適切なインデックスにDropDownListコントロールを取得/設定するvalを使用しています。

さて、これは全体のコードである(それだけではない):

<?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> 
+0

私は最初のアプローチがうまくいかないことに驚いています。 2番目のアプローチでパフォーマンスの問題が発生していることにも驚いています。私は、ループが開始するときのループの反復の「既知の」数であるため、2番目のループがより効率的であることを期待していました。おそらく、あなたがしようとしていることを詳しく説明したり、問題を説明する実行可能なサンプルを提供したりすることができます。 – JeffryHouser

+0

最初の方がうまくいけば、2番目のアプローチは最初のアプローチよりも優れているかもしれません...もっと詳しく説明します... – huff

答えて

8

実際for eachループは、forループ通常よりも少し遅いです。 For VS Foreach on Array performanceへの答えを見てください。

あなたの質問に答えるには、なぜあなたのfor eachループがうまくいかないのですか?残念ながら、このタイプのループは特定の種類のクラスに対してのみ機能します。私の知る限りでは、それらは以下のとおりです。

  • Array
  • Vector
  • XML
  • XMLList
  • for eachループのために必要な機能を実装Proxyを拡張するクラス。 ListCollectionViewとそのサブクラスArrayCollectionXMLListCollectionは私が知っている唯一のものです。彼らは(Arrayのような)Flash Playerでネイティブオブジェクトではありません、彼らはProxyクラスを拡張していないので、ArrayListよう

Collectionクラスはfor eachループでは動作しません。

したがって、最も簡単なことは、単純なforループを使用することです。これらのループはfor eachループよりもさらに高速です。