PDA

Volledige versie bekijken : List.selectedIndex vertraging?


Dauntless
%Europe/Berlin %784 %2008, 19:49
Hey,

Ik wist niet meteen een betere manier om het te omschrijven...
Situatie:
- Een list, DP = een ArrayCollection, gebind
- Twee knoppen: 1 om een item toe te voegen, 1 om te verwijderen (het geselecteerde item)

Probleem:
Eerst voeg ik 4 items toe. Daarna selecteer ik het eerste item en verwijder het. Volgens het output vak is het 1ste item in de lijst geselecteerd, maar grafisch zie je dat het tweede item geselecteerd is. Het probleem doet zich enkel voor in het geval hierboven, en dus niet wanneer je bv het laatste item selecteert, of bv het tweede. Ook bv: Er zijn twee items in de lijst, ik verwijder het 1ste element. Het eerste (en enige) element is dan geselecteerd, maar de selectedIndex staat wel degelijk terug op 1! (Grafisch is dit dus wel niet te zien)

De test files:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Panel x="136" y="250" width="208" height="249" layout="absolute">
<mx:List x="10" y="10" width="168" height="124" id="myList" dataProvider="{myCollection}" change="show()"></mx:List>
<mx:Button x="10" y="172" label="Add" click="addItem()"/>
<mx:Button x="113" y="172" label="Delete" click="removeItem()"/>
<mx:TextInput x="10" y="142" width="168" id="output"/>
</mx:Panel>

<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable] private var myCollection:ArrayCollection = new ArrayCollection();
private var counter:Number = 0;
private function addItem():void
{
var ob:Object = new Object();
ob.label = "Item " + counter ++;
myCollection.addItem(ob);
myList.selectedIndex = myCollection.length - 1;
show();
}

private function removeItem():void
{
myCollection.removeItemAt(myList.selectedIndex);
myList.selectedIndex = 0;
show();
}

private function show():void
{
output.text = "Selected = " + myList.selectedItem.label;
}
]]>
</mx:Script>
</mx:Application>

Waar gaat het fout?

Greets!

Dauntless
%Europe/Berlin %453 %2008, 11:53
Uiteraard ben ik verder blijven zoeken en heb deze blog entree gevonden:
http://butterfliesandbugs.wordpress.com/2007/11/08/workaround-for-selectedindex-on-tree-not-showing-up/
en
https://bugs.adobe.com/jira/browse/SDK-11424?page=com.atlassian.jira.plugin.system.issuet abpanels:all-tabpanel

En ook in dit geval, wanneer ik een validateNow() tussen het verwijderen & het toekennen zet, werkt het ! Spijtig dat Adobe hier toch geen "uitzondering" op wil maken mbt het standaard gedrag van het invalidaten ... Dit lijkt me toch iets dat wel vaker gebruikt wordt ?

Toch bedankt aan iedereen om mee te denken ;).

TheDutch
%Europe/Berlin %470 %2008, 12:17
Jij veranderd je array collection, wat betekend dat de List geupdate moet worden. Dit updaten gebeurt bij de volgende update cycle van de Flash Player. Wanneer jij in de huidige update cycle de selected index op '0' zet dan is de List (visueel) nog niet geupdate maar de array collection wel. Wanneer er dan geupdate wordt dan past de List ook zijn selected index zelf aan aan dat van de nieuwe data in de array collection. Hij merkt dat de selectedIndex -1 moet zijn en doet daarom +1. Hierdoor zie jij "Item 2" geselecteerd en niet "Item 1". Je moet daarom in dit soort gevallen altijd validateDisplayList() uitvoeren om de display list direct te updaten en niet te wachten. Dan blijft alles synchroon lopen :)

Zo dus:

private function removeItem():void
{

myCollection.removeItemAt(myList.selectedIndex);
myList.validateDisplayList();
myList.selectedIndex = 0;

show();
}


EDIT: Ik zie dat je al zoiets gevonden had en reeds hebt neergezet. Was druk bezig met het tikken van deze uitleg, dus had niet door dat jij al een oplossing had gevonden :).

TheDutch
%Europe/Berlin %484 %2008, 12:38
Spijtig dat Adobe hier toch geen "uitzondering" op wil maken mbt het standaard gedrag van het invalidaten ... Dit lijkt me toch iets dat wel vaker gebruikt wordt ?

Het is een logische beslissing hoor. Op deze manier heeft de ontwikkelaar volledig controle over de updates na het wijzigen van iets externs zoals de data provider of item renderers. Wanneer alles direct zou wijzigen dan zou dit een performance issue kunnen worden bij bepaalde applicaties. Soms wil je dat de visuele updates wachten tot alles uitgevoerd is en dan een enkele update om het aangepaste zichtbaar te maken. Het is dus een keuze geweest om performance redenen en de vrijheid voor de ontwikkelaar om de performance met betrekking tot de visuele updates enigzins te kunnen bepalen op deze manier.

Buiten dat ik dus geheel achter de beslissing van Adobe sta, vind ik wel dat het beter gedocumenteerd had mogen worden. Veel Flash programmeurs zijn onbekend met het invalidation princiepe en verwachten een andere werking, zoals in de oude AVM (AS1/2). Het is een goede feature voor programmeurs die er vanaf weten, maar kan een hel zijn voor diegene die niet weten waar ze zoeken moeten. Het had daarom misschien beter geweest om er een soort van setting van te maken waarbij standaard validation op FALSE staat maar op TRUE gezet kan worden voor de meer ervaren programmeurs die het nodig hebben (autoValidation?). Wie weet in Flex 4, zal eens gaan polsen hier en daar :).

Dauntless
%Europe/Berlin %516 %2008, 13:24
Buiten dat ik dus geheel achter de beslissing van Adobe sta, vind ik wel dat het beter gedocumenteerd had mogen worden. Veel Flash programmeurs zijn onbekend met het invalidation princiepe en verwachten een andere werking, zoals in de oude AVM (AS1/2). Het is een goede feature voor programmeurs die er vanaf weten, maar kan een hel zijn voor diegene die niet weten waar ze zoeken moeten.
Dat probleem had ik inderdaad ja... Ik ga zoeken bij selectedItem en selectedIndex, maar bij beiden is de uitleg minimaal en staat er zeker geen referentie naar een uitleg over het invalidatie principe. (Misschien staat die bovenaan bij de classe wel, maar toch ...).

Toch bedankt voor je replies, Erwin ! :)

TheDutch
%Europe/Berlin %934 %2008, 23:25
Graag gedaan hoor! De reden waarom het niet bij selectedIndex en selectedItem staat is omdat het daar eigenlijk niets mee te maken heeft. Het heeft te maken met wijzigingen die van invloed zijn op het visuele maar pas bij de volgende update cycle doorgevoerd worden. Het heeft dus direct te maken met het visueel onderhoud en valt dus onder het UIComponent.

Heb ook nog even zitten Googlen maar er is daar ook zeer weinig over te vinden. Bij de (in)validation methods in de LiveDocs onder UIComponent staan wel korte uitleggen, maar niet zeer uitgebreid. Zal eens kijken of ik er binnenkort een kort artikel over kan schrijven zodat het allemaal wat duidelijker wordt, ook per (in)validation method :).

Dauntless
%Europe/Berlin %939 %2008, 23:32
Dat zou cool zijn! Ik kijk er naar uit :).