Frage

Die vorgeschlagene UX, die ich zu erreichen versuche, ist dies:

  1. benutzer klickt auf Menüelement (über eine listBase-Unterklasse:beispielsweise.Tastenleiste oder Registerkartenleiste)
  2. anfängliche Auswahl verhindern
  3. überprüfen Sie, ob der Benutzer Probleme beheben muss (z.nicht gespeicherte Daten in einem Formular usw.)
  4. wenn gültig, nehmen Sie die Auswahl und setzen Sie die Listenbasis auf diesen SelectedIndex, andernfalls zeigen Sie dem Benutzer Warnungen an und brechen Sie den Auswahlvorgang vollständig ab

Dies funktioniert nicht wie erwartet.Verwenden des IndexChangeEvent .DAS Ändern des Typs und des preventDefault funktioniert, um die Auswahl zu beenden, aber in Schritt 4, wenn ich den SelectedIndex der listBase programmgesteuert einstelle, wird dann versucht, das Änderungsereignis erneut zu versenden (dies trotz der Behauptungen der API-Dokumente).

Hier ist ein Beispielanwendungs-Quellcode, wenn Sie dies selbst ausprobieren möchten.Ich freue mich auf Ihre Kommentare und Lösungen.

Danke.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>
War es hilfreich?

Lösung

Mit Blick auf das SDK, das IndexChangeEvent.CHANGING ereignis ist eigentlich vermeidbar - trotz Dokumentation hier sagt, dass cancelable falsch ist, also mein schlechtes daran (obwohl ASDoc ein wenig seitwärts gegangen ist), aber von hier aus werden die Dinge ein wenig interessant.

In ListBase @ 1296 wird dies immer nur von der commitSelection(dispatchEvents:Boolean = true) Methode.In ButtonBarBase:dataProvider_changeHandler() ist der einzige Ort, der speziell aufruft, das Ereignis nicht zu versenden, sondern in ListBase, es heißt in commitProperties@939, wenn ein vorgeschlagener Auswahlindex vorhanden ist.

Wenn Sie also aus Ihrem obigen Code versuchen, die Auswahl festzulegen, wird dies die commitSelection aufrufen, von der ich glaube, dass sie das Problem mit dem Aufrufstapel verursacht.Die Zeitverzögerung wird das Problem nur verschlimmern, da die Benutzeroberfläche nach 500 ms mindestens einmal ihren Ungültigkeitszyklus durchlaufen hat, was bedeutet, dass die commitSelection aufgrund eines invalidateProperties flag wird von der gesetzt proprosedSelectionIndex schließlich stammen aus setSelectedIndex @729

Also, wie man das behebt.
Ich würde versuchen, die Verhinderung nur durchzuführen, wenn die Validierung fehlschlägt, andernfalls kann sie wie gewohnt fortgesetzt werden.Wenn es fehlschlägt, rufen Sie prevent auf, setzen Sie ein errorString oder gleichwertig, aber versuchen Sie nicht, die Auswahl zu ändern.

[bearbeiten] Lesen Sie Riastars Kommentar, und ich stimmte nur der gleichen 'Lösung' zu.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top