Domanda

Quindi il mio problema è che SelectedIndex non viene aggiornato quando utilizzo NextSlide () e Prevalide (), che vengono eseguiti quando faccio clic su due pulsanti. SelectedIndex funziona quando faccio clic sugli elementi nell'elenco. Che cosa sto facendo di sbagliato? Devo spedire alcuni eventi? Ci sono trucchi per farlo con i pulsanti?

Questa è la mia classe di playlist

public class Playlist extends List
        {
            private var dispatcher:Dispatcher;

            public function Playlist()
            {
                super();

                this.dragEnabled = true;
                this.dragMoveEnabled = true;
                this.dropEnabled = true;
                this.allowMultipleSelection = true;   
                this.dispatcher = new Dispatcher();
            }

            public function handleSelection(event:PlaylistEvent):void
            {
                if (event.type == PlaylistEvent.ITEMS_SELECTED){
                    selectItem(event.index, event.count);
                    selectedIndex = event.index;
                }
            }

            private function selectItem(index:Number, count:Number):void
            {
                var tempArray:Array = this.dataProvider.toArray();
                var indiceVector:Vector.<int> = new Vector.<int>();
            var itemVector:Vector.<Object> = new Vector.<Object>();
            var n:int = 1;
            for (var i:int=0;i<tempArray.length;i++){
                var item:PlaylistItem = tempArray[i];
                if (i<index) deselectItem(item);
                else if (i<index+count) {
                    item.Selected=true;
                    indiceVector[count-n] = i;
                    itemVector[count-n++] = item;

                }
                else deselectItem(item);
            }
            selectedItems = itemVector;
            selectedIndices = indiceVector;
        }

        private function deselectItem(item:PlaylistItem):void
        {
            item.Selected = false;
        }


        public function nextSlide():void
        {
            if (dataProvider.length == 0) return;
            var index:int = selectedIndex;

            if (index < 0) {
                var event1:PlaylistEvent = new PlaylistEvent(PlaylistEvent.ITEMS_SELECTED, 0, 1);
                dispatcher.dispatchEvent(event1);
                return;
            }

            var item:PlaylistItem = PlaylistItem(dataProvider.getItemAt(index));
            if (index < dataProvider.length-1) {
                trace("going to index", index+1);
                var event:PlaylistEvent = new PlaylistEvent(PlaylistEvent.ITEMS_SELECTED, index+1, 1);
                dispatcher.dispatchEvent(event);
                return;
            }
        }

        public function previousSlide():void
        {
            if (dataProvider.length == 0) return;
            var index:int = selectedIndex;
            if (index < 0) {
                var event1:PlaylistEvent = new PlaylistEvent(PlaylistEvent.ITEMS_SELECTED, 0, 1);
                dispatcher.dispatchEvent(event1);
                return;
            }

            var item:PlaylistItem = PlaylistItem(dataProvider.getItemAt(index));
            if (index > 0) {
                var event:PlaylistEvent = new PlaylistEvent(PlaylistEvent.ITEMS_SELECTED, index-1, 1);
                dispatcher.dispatchEvent(event);
                return;
            }
        }
    }
}

Questo è il mio mate eventmap

<?xml version="1.0" encoding="utf-8"?>
<mate:EventMap xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:mate="http://mate.asfusion.com/"
               xmlns:air="de.websector.mate.extensions.air.*">
    <fx:Script>
        <![CDATA[

            import components.Playlist;
            import events.PlaylistEvent;
            import mx.controls.Alert;
            import mx.events.*;
            import mx.logging.*;
            import mx.logging.Log;
            import spark.components.Application;

            private var logger:ILogger;     
            private function initLogger():void{
                logger = Log.getLogger("MainEventMap");
                trace("started init maineventmap");
            }

        ]]>
    </fx:Script>
    <fx:Declarations>
        <mate:EventHandlers type="{FlexEvent.APPLICATION_COMPLETE}">
            <mate:InlineInvoker method="initLogger"/>
            <mate:ObjectBuilder generator="{MainManager}"/>
            <mate:EventAnnouncer type="{InitEvent.SYSTEM_INIT_COMPLETE}" />
        </mate:EventHandlers>
        <mate:Injectors target="{Playlist}">
            <mate:PropertyInjector targetKey="dataProvider" source="{MainManager}" sourceKey="playlistItems" />
        </mate:Injectors>
        <mate:Injectors target="{MainManager}">
            <mate:PropertyInjector targetKey="playlist" source="{Playlist}" />
        </mate:Injectors>

        <!-- Playlist events! __________________________________________________________________________________________________-->

        <mate:EventHandlers type="{PlaylistEvent.ITEMS_SELECTED}">
            <mate:MethodInvoker generator="{Playlist}" method="handleSelection" arguments="{event}" />
        </mate:EventHandlers>


    </fx:Declarations>

</mate:EventMap>
È stato utile?

Soluzione

Mate non è in grado di popolare la tua variabile di dispatcher privato con un riferimento al suo bus di eventi, quindi la mappa degli eventi non "sente" l'evento che stai inviando su di essa e non puoi invocare il tuo metodo.

Questo sembra un modo sciocco per invocare un metodo sullo stesso componente, e penso che questo sia un segno che sai che dovresti separare la logica in qualche modo. Quello che suggerirei è che hai un modello di presentazione che contiene DataProvider e SelectedIndex e inietta un riferimento a quello. Quindi, l'elenco si legarà a DataProvider e SelectedIndex. Il PM può ascoltare gli eventi sul bus per mantenere SelectedIndex oppure è possibile utilizzarlo direttamente dal componente Visualizza.

In questo modo, quando ti rendi conto che è un po 'problematico avere una sottoclasse di elenco che contiene pulsanti, puoi allegare la nuova sottoclasse di gruppo che ha un elenco e pulsanti senza problemi.

Per un esempio di come iniettare correttamente il bus evento (che mostra comodamente come utilizzare un PM), dai un'occhiata http://www.developria.com/2010/05/refactoring-with-mate.html. Sembra che tu abbia un buon inizio per capire l'evento Bus, ma potresti voler ottenere un po 'più di dettagli guardando http://www.developria.com/2010/05/pass-the-eventdispatcher-pleas.html .

Altri suggerimenti

Come qualcuno ha sottolineato su #Flex (IRC: //irc.freenode.net/flex), l'errore sta usando MethodInvoker In quanto costruisce una nuova istanza della classe e quindi esegue il metodo HandleSlection su tale istanza. Ho risolto questo problema iniettando l'istanza di playlist in eventmap e usando Inlineinvoker.

<mate:EventHandlers type="{PlaylistEvent.ITEMS_SELECTED}">
        <mate:InlineInvoker method="{playlist.handleSelection}" arguments="{event}" />
    </mate:EventHandlers>

Quindi il problema era nell'uso del framework Mate, non in flex o da databinding o eventdispatching.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top