Итерация dataProvider в flex - PullRequest
       12

Итерация dataProvider в flex

4 голосов
/ 01 декабря 2010

Мне интересно ... Я хочу перебрать dataProvider в компоненте, который основан на DropDownList. Первое, что не сработало (скомпилировано, но никогда не повторялось), было:

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 = "@ {variable}" ), но к значению переменной внутри ArrayCollection.

Скажем, у вас есть dataProvider с двумя объектами: {a:'5', nmb:'five', blabla:'cinco'} и {a:'39', nmb:'thirty-nine', 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>

1 Ответ

8 голосов
/ 02 декабря 2010

На самом деле for each циклы немного медленнее, чем нормальные for циклы.Посмотрите на ответ Для VS Foreach по производительности массива .

Чтобы ответить на ваш вопрос, почему ваш for each цикл не работает.К сожалению, этот тип цикла работает только для определенных типов классов.Насколько я знаю, это:

  • Array
  • Vector
  • XML
  • XMLList
  • и классы, расширяющие Proxy, которые реализуют функции, необходимые для циклов for each.ListCollectionView и его подклассы ArrayCollection и XMLListCollection - единственные, о которых я знаю.

Классы коллекций, такие как ArrayList, не работают с циклами for each, поскольку они не являются нативными объектамив Flash Player (например, Array), и они не расширяют класс Proxy.

Итак, лучшее, что вы можете сделать, это использовать простые циклы for, и эти циклы даже быстрее, чемfor each петли.

...