Почему мой TileList selectedIndex не обновляется?

В коде ниже представленныйAlbumIndex используется для управления selectedIndex TileList. Пункт «пять» изначально выбран. При каждом нажатии кнопки первый элемент в массиве удаляется, а представленныйAlbumIndex уменьшается.

Теоретически выбранный индекс должен оставаться на «пяти» каждый раз, когда нажимается кнопка (пока «пять» не будет удалено). Это работает таким образом для первого нажатия кнопки. Однако при нажатии на 2-ю кнопку подсветка почему-то меняется на «шесть». Кроме того, TileList selectedIndex всегда отстает на единицу.

Почему?

Я попытался заглянуть в ListBase и отследить selectedIndex. Похоже, что selectedIndex сначала обновляется до правильного индекса, но затем в какой-то момент возвращается к правильному index+1. Я не знаю, почему он отступает.

Кажется, это связано с тем, что я выполняю удаление поставщика данных и изменение индекса в одной и той же операции.

Есть ли какая-то функция в TileList, которую я мог бы переопределить, чтобы поддерживать selectedIndex в актуальном состоянии?

Стив

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="absolute"
        applicationComplete="init()">
    <mx:Label id="label1" text="{'TileList selected index: ' + albumsThumbnailList.selectedIndex}"
        x="255" y="55" width="234"/>
    <mx:Label id="label2" text="{'Presented album index: ' + presentedAlbumIndex}" x="255" y="81" width="234"/>
    <mx:TileList id="albumsThumbnailList" direction="vertical"
        dataProvider="{presentedAlbums}"
        selectedIndex="{presentedAlbumIndex}" x="25" y="13"
        change="presentedAlbumIndex=albumsThumbnailList.selectedIndex"
        height="400"/>
    <mx:Button click="test2()" x="297" y="150"/>

    <mx:Script>
        <![CDATA[
            import mx.events.CollectionEvent;
            import mx.collections.ArrayCollection;
            private var _includedAlbums:ArrayCollection = new
                ArrayCollection(["zero","one","two","three","four","five","six","seven"]);

            [Bindable]
            private var presentedAlbumIndex:int = 5;

            private function init():void {

                _includedAlbums.addEventListener(CollectionEvent.COLLECTION_CHANGE,
                    function():void {
                        dispatchEvent(new Event("albumDataChanged"));
                    }
                );
            }

            public function test2():void {
                _includedAlbums.removeItemAt(0);
                presentedAlbumIndex--;
            }

           [Bindable(event="albumDataChanged")]
           public function get presentedAlbums():ArrayCollection {
               return _includedAlbums;
           }

        ]]>
    </mx:Script>

</mx:Application>

person Stephen Horvath    schedule 14.08.2009    source источник


Ответы (1)


С прослушивателем COLLECTION_CHANGED список получает новый поставщик данных, поскольку это асинхронное событие, которое запускается после привязки к selectedIndex. Удалив этот прослушиватель и не предоставляя новый поставщик данных коллекции при каждом изменении коллекции, привязка selectedIndex работает должным образом.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="absolute"
        applicationComplete="init()">
    <mx:Label id="label1" text="{'TileList selected index: ' + albumsThumbnailList.selectedIndex}"
        x="255" y="55" width="234"/>
    <mx:Label id="label2" text="{'Presented album index: ' + presentedAlbumIndex}" x="255" y="81" width="234"/>
    <mx:TileList id="albumsThumbnailList" direction="vertical"
        dataProvider="{presentedAlbums}" x="25" y="13" 
        selectedIndex="{presentedAlbumIndex}"
        height="400"/>
    <mx:Button click="test2()" x="297" y="150"/>

    <mx:Script>
        <![CDATA[
            import mx.events.CollectionEvent;
            import mx.collections.ArrayCollection;
            private var _includedAlbums:ArrayCollection = new
                ArrayCollection(["zero","one","two","three","four","five","six","seven"]);

            [Bindable]
            private var presentedAlbumIndex:int = 5;

            private function init():void {

            }

            public function test2():void {
                _includedAlbums.removeItemAt(0);
                presentedAlbumIndex--;
            }

           [Bindable(event="albumDataChanged")]
           public function get presentedAlbums():ArrayCollection {
               return _includedAlbums;
           }

        ]]>
    </mx:Script>

</mx:Application>
person Joel Hooks    schedule 14.08.2009
comment
Нет, по-прежнему возникает та же проблема при вызове refresh() перед уменьшением индекса. Я не привязываюсь напрямую к _includedAlbums, потому что в моем реальном приложении TileList находится в отдельном классе. - person Stephen Horvath; 14.08.2009
comment
Удаление слушателя COLLECTION_CHANGED заставляет его работать правильно. Это обязательно. - person Joel Hooks; 14.08.2009
comment
В моем случае требуется COLLECTION_CHANGE. Я использую событие COLLECTION_CHANGE для уведомления слушателей о действиях глубоко внутри иерархии поставщиков данных. В моем приложении у меня на самом деле есть другие привязки, также установленные для представленных альбомов, и все они вызывают проблему с тем, что selectedIndex не обновляется. Событие COLLECTION_CHANGE является асинхронным и срабатывает позже — это объясняет, почему selectedIndex сначала уменьшается, а затем снова увеличивается. Любая идея, где в ListBase происходит повторное увеличение поставщика данных? Возможно, я могу переопределить его, чтобы не обновлять выбранный индекс. - person Stephen Horvath; 14.08.2009
comment
Нет ничего плохого в использовании COLLECTION_CHANGED, просто не используйте его для привязки dataProvider к функции. Он уменьшает selectedIndex в: protected function collectionChangeHandler(event:Event):void Зверь функции там... - person Joel Hooks; 14.08.2009