Domanda

Sto usando Adobe Flash Builder 4 Premium. Ho un mx:DataGrid e a s:TextInput, e sto cercando di impostare una casella di ricerca che filtra il datagrid su ciascuna pressione del tasto.

Questa pagina mostra un esempio quasi perfetto di ciò che sto cercando di fare, tranne per il fatto che lo sto preparando in a s:TitleWindow, che viene allevato come popup usando il popupmanager. L'elenco che sto cercando di filtrare può essere molto grande. È un elenco di nomi utente, recuperati da un database MySQL tramite PHP. Dal momento che può essere così grande, voglio che l'elenco venga popolato una volta nell'applicazione principale e quindi referenziato nella finestra popup in modo che non debba recuperare tutti i nomi utente ogni volta che l'utente apre il popup.

Ho tutto questo funzionare bene per la prima volta che tiri su il popup, ma se lo chiudi e lo rialzi, ricevo questo errore di runtime:

Flash runtime error

Ricevo anche questo errore se provo a impostare il filterFunction Torna a Null poco prima di chiudere il popup.

Vedi il codice di esempio di seguito:

Applicazione principale:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx">
    <fx:Script>
        <![CDATA[
            import mx.collections.*;
            import mx.managers.PopUpManager;

            [Bindable] public var allMembersList:ArrayCollection;

            private function openPopup():void
            {
                var popupInstance:popup = PopUpManager.createPopUp(this as DisplayObject, popup, true) as popup;
                PopUpManager.centerPopUp(popupInstance);
            }
        ]]>
    </fx:Script>
    <s:Button label="Open Popup" click="openPopup()"/>
</s:Application>



Apparire:

<?xml version="1.0" encoding="utf-8"?>
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx"
               xmlns:model="services.model.*"
               tabChildren="false"
               close="close()">
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.core.FlexGlobals;
            import mx.managers.PopUpManager;

            private function getUsers(startsWith:String = ""):void
            {
                if (FlexGlobals.topLevelApplication.allMembersList == null)
                {
                    FlexGlobals.topLevelApplication.allMembersList = new ArrayCollection();
                    getUsersResult.token = php.getUsers();
                }

                FlexGlobals.topLevelApplication.allMembersList.filterFunction = function(item:Object):Boolean
                {
                    return item.username.match(new RegExp("^"+ startsWith, "i"));
                };
                FlexGlobals.topLevelApplication.allMembersList.refresh();
                grdMemberList.dataProvider = FlexGlobals.topLevelApplication.allMembersList;
            }

            private function getUsersResultHandler():void
            {
                var users:Object = getUsersResult.lastResult;
                for each (var user:Object in users)
                    FlexGlobals.topLevelApplication.allMembersList.addItem({"username":user.username});
            }

            private function close():void
            {
                FlexGlobals.topLevelApplication.allMembersList.filterFunction = null;
                FlexGlobals.topLevelApplication.allMembersList.refresh();
                PopUpManager.removePopUp(this);
            }
        ]]>
    </fx:Script>
    <fx:Declarations>
        <model:MODEL id="php" fault="{Alert.show('There was a PHP error!\nPlease note the steps taken to produce this error and call support.\n\nError Message: '+ event.fault.faultDetail, 'Error');}" showBusyCursor="false"/>
        <s:CallResponder id="getUsersResult" result="getUsersResultHandler()"/>
    </fx:Declarations>

    <mx:DataGrid id="grdMemberList" creationComplete="getUsers()">
        <mx:columns>
            <mx:DataGridColumn headerText="Member List" dataField="username"/>
        </mx:columns>
    </mx:DataGrid>
    <s:TextInput id="txtUsername" keyUp="{ if (event.charCode != 13 && event.charCode != 0) getUsers(txtUsername.text); }"/>
</s:TitleWindow>

L'app sembra ancora funzionare come previsto, nonostante l'errore, ma non sono un fan di avere errori nella mia app, quindi mi piacerebbe davvero capire cosa sta causando questo problema.

Grazie!

È stato utile?

Soluzione

Si scopre che il problema è stato con il tabChildren proprietà. La documentazione dice di non utilizzare questa proprietà in Flex, ma di utilizzare hasFocusableChildren invece. Non sono sicuro del perché questo problema si sia mostrato solo una volta che stavo cercando di impostare il filterFunction.

Il motivo per cui stavo impostando tabChildren A False è stato in modo che la funzionalità chiave della scheda predefinita (focus di commutazione) non si svolgesse, in modo da poter controllare quel comportamento da solo. Il hasFocusableChildren La proprietà non funziona (o almeno, impostarla su False non impedisce alla messa a fuoco del tasto TAB), quindi potrei aver bisogno di provare un altro mezzo per catturare l'evento del tasto Tab e fermarlo.


MODIFICARE:

Per chiunque sia interessato (anche se non ha davvero nulla a che fare con il post originale), la soluzione era cambiare:

<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               xmlns:model="services.model.*"
               width="1000"
               height="550"
               tabChildren="false"
               close="close()">

a:

<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               xmlns:model="services.model.*"
               width="1000"
               height="550"
               keyFocusChange="{ event.preventDefault(); }"
               close="close()">

Altri suggerimenti

Non provo mai a testare il tuo codice (perché necessita anche del lato server) ma penso che non dovresti ripristinare il filtro su NULL. In alternativa, è possibile impostarlo su una funzione che restituisce sempre vero.

function defaultFilterFunc( item: Object ): Boolean { return true; }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top