Pregunta

La UX propuesta que estoy tratando de lograr es esta:

  1. el usuario hace clic en el elemento del menú (a través de una subclase listBase:p.ej.Barra de botones o barra de pestañas)
  2. impedir la selección inicial
  3. validar si el usuario necesita abordar problemas (p. ej.datos no guardados en un formulario, etc.)
  4. si es válido, tome la selección y establezca listBase en ese índice seleccionado; de lo contrario, presente advertencias al usuario y cancele el proceso de selección por completo

Esto no funciona como cabría esperar.Utilizar el tipo IndexChangeEvent.CHANGING y preventDefault funciona para eliminar la selección, pero en el paso 4, cuando estoy configurando mediante programación el índice seleccionado de listBase, intenta volver a enviar el evento CHANGING (esto a pesar de lo que afirman los documentos de la API).

Aquí hay un código src de aplicación de muestra si desea probarlo usted mismo.Espero sus comentarios y soluciones.

Gracias.j

http://snipt.org/vUji3#expand

<?xml version="1.0" encoding="utf-8"?>
<s:Application minWidth="955" minHeight="600"
           xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx"
           xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
    <![CDATA[
        import flash.utils.setTimeout;

        import mx.core.mx_internal;

        import spark.events.IndexChangeEvent;

        use namespace mx_internal;

        [Bindable]
        private var doPreventDefault:Boolean;

        [Bindable]
        private var delayMS:uint = 500;

        private function buttonbar_changingHandler( event:IndexChangeEvent ):void
        {
            // TODO Auto-generated method stub
            if ( doPreventDefault )
            {
                event.preventDefault();

                setTimeout( delayedLogic, delayMS, event.newIndex );
            }
        }

        private function delayedLogic( index:int ):void
        {
            //disabling this results in an endless loop of trying to set the selected index
            //              doPreventDefault = false;

            //this should NOT be hitting the changing handler since we're supposed to be dispatching a value commit event instead.
            bb.setSelectedIndex( index, false );
        }
    ]]>
</fx:Script>

<fx:Declarations>

    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>

<s:layout>
    <s:VerticalLayout horizontalAlign="center"/>
</s:layout>

<s:ButtonBar id="bb"
             changing="buttonbar_changingHandler(event)">
    <s:dataProvider>
        <s:ArrayList>
            <fx:String>btn 0</fx:String>
            <fx:String>btn 1</fx:String>
            <fx:String>btn 2</fx:String>
        </s:ArrayList>
    </s:dataProvider>
</s:ButtonBar>

<s:CheckBox label="preventDefault?"
            selected="@{ doPreventDefault }"/>

<s:NumericStepper maximum="5000" minimum="500"
                  stepSize="500" value="@{ delayMS }"/>
</s:Application>
¿Fue útil?

Solución

Mirando el SDK, el IndexChangeEvent.CHANGING En realidad, el evento se puede prevenir, a pesar de la documentación. aquí dice que cancelable es falso, así que estoy mal por eso (aunque ASDoc se desvió un poco), sin embargo, las cosas se ponen un poco interesantes a partir de aquí.

En ListBase @1296 esto solo se envía desde el commitSelection(dispatchEvents:Boolean = true) método.En ButtonBarBase:dataProvider_changeHandler() es el único lugar que llama específicamente a no enviar el evento, pero en ListBase, se llama en commitProperties@939 cuando hay un índice de selección propuesto.

Entonces, según el código anterior, si está intentando configurar la selección, esto llamará a commitSelection, lo que creo que está causando el problema de la pila de llamadas.El retraso del temporizador solo exacerbará el problema, ya que a los 500 ms la interfaz de usuario habrá pasado por su ciclo de invalidación al menos una vez, lo que significa que commitSelection se ejecutará nuevamente debido a un invalidateProperties La bandera se está configurando desde el proprosedSelectionIndex eventualmente proveniente de setSelectedIndex @729

Entonces, ¿cómo solucionar este problema?
Consideraría hacer la prevención solo si la validación falla; de lo contrario, permitiría que continúe normalmente.Si falla, llame a la prevención, establezca un errorString o equivalente, pero no intente cambiar la selección.

[editar] Lea el comentario de RiaStar y estuve de acuerdo con la misma 'solución'.

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