Pregunta

Entonces, mi problema es que SelectedIndex no se actualiza cuando uso NextSlide () y Prevslide (), que se ejecutan cuando hago clic en dos botones. SelectedIndex funciona cuando hago clic en los elementos de la lista. ¿Qué estoy haciendo mal? ¿Tengo que enviar algunos eventos? ¿Hay algún truco para hacerlo con botones?

Esta es mi clase de lista de reproducción

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;
            }
        }
    }
}

Este es mi compañero event map

<?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>
¿Fue útil?

Solución

Mate no puede completar su variable de despachador privado con una referencia a su bus de eventos, por lo que el mapa del evento nunca "escucha" el evento que está enviando y no puede invocar su método.

Esta parece una forma tonta de invocar un método en el mismo componente, y creo que esta es una señal de que sabe que debe separar la lógica de alguna manera. Lo que sugeriría es que tiene un modelo de presentación que contiene Dataprovider y SelectedIndex, e inyecte una referencia a eso. Luego, su lista se unirá a DataProvider y SelectedIndex. El PM puede escuchar eventos en el bus para mantener seleccionada INDEX, o puede operarlo directamente desde el componente de vista.

De esa manera, cuando te das cuenta de que es un poco problemático tener una subclase de lista que tiene botones, puede adjuntar la nueva subclase de grupo que tiene una lista y botones sin ningún problema.

Para obtener un ejemplo de cómo inyectar correctamente el bus de eventos (que muestra convenientemente cómo usar un PM), consulte http://www.developria.com/2010/05/refactoring-with-mate.html. Parece que tienes un buen comienzo para comprender el autobús del evento, pero es posible que desee obtener un poco más de detalle mirando http://www.developria.com/2010/05/pass-the-eventdispatcher-plesas.html .

Otros consejos

Como alguien señaló en #flex (irc: //irc.freenode.net/flex), el error es usar Methodinvoker ya que construye una nueva instancia de la clase y luego ejecuta el método de selección de manejables en dicha instancia. Resolví este problema inyectando la instancia de la lista de reproducción en el EventMap y usando En línea.

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

Entonces, el problema estaba en el uso del marco Mate, no en Flex o Databinding o EventDispatching.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top