Question

Je veux ajouter la recherche en direct à une liste dont le fournisseur de données XML est un très grand. pour simplifier, supposons que mon XML est juste une liste des pays 180ish du monde:

package
{
//Imports
import fl.controls.List;
import fl.data.DataProvider;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;

//Class
public class LiveSearchXMLList extends Sprite
    {
    //Variables
    private var XMLData:XML;
    private var dp:DataProvider;
    private var list:List;

    //Constructor
    public function LiveSearchXMLList()
        {
        addEventListener(Event.ADDED_TO_STAGE, init);
        }

    //Initialization
    private function init(evt:Event):void
        {
        removeEventListener(Event.ADDED_TO_STAGE, init);

        //Download XML File
        var XMLLoader:URLLoader = new URLLoader();
        XMLLoader.addEventListener(IOErrorEvent.IO_ERROR, IOEventErrorHandler);
        XMLLoader.addEventListener(Event.COMPLETE, XMLLoaderCompleteEventHandler);
        XMLLoader.load(new URLRequest( /* COUNTRY_LIST_XML_FILE */ ));
        }

    //XMLLoader Error Handler
    private function IOEventErrorHandler(evt:IOErrorEvent):void
        {
        //Remove Event Listeners
        evt.target.removeEventListener(IOErrorEvent.IO_ERROR, IOEventErrorHandler);
        evt.target.removeEventListener(Event.COMPLETE, XMLLoaderCompleteEventHandler);

        //Throw Error
        throw(evt.text);
        }

    //XMLLoader Complete Handler
    private function XMLLoaderCompleteEventHandler(evt:Event):void
        {
        //Remove Event Listeners
        evt.target.removeEventListener(IOErrorEvent.IO_ERROR, IOEventErrorHandler);
        evt.target.removeEventListener(Event.COMPLETE, XMLLoaderCompleteEventHandler);

        //Assign XMLData
        XMLData = new XML(evt.target.data);

        createList();
        }

    //List
    private function createList():void
        {
        //Assign And Alphabetize Data
        dp = new DataProvider(XMLData);
        dp.sortOn("countryName");

        //Create List Object
        list = new List();
        list.width = 400;
        list.height = 400;
        list.x = list.y = 25;
        list.labelField = "countryName";
        list.dataProvider = dp;
        }
    }
}

sont renseignés par l'élément XML de la <countryName> et alphabétisé les labelFields de la liste.

je voudrais créer un champ de saisie de texte qui écoutera pour les touches et mettre à jour la liste en fonction de la chaîne d'entrée correspondant aux valeurs des éléments de CountryName. Par conséquent, si j'entre « peut » dans le champ de texte, la liste va soudainement être réduite à seulement 5 lignes:

  • Samoa américaines
  • Canada
  • République centrafricaine
  • République Dominicaine
  • Cité du Vatican

bien sûr, la recherche en direct devrait être non destructif et - presse supprimer une fois de sorte que le champ de recherche se lit maintenant « ca », ce qui augmente la liste 5 de la ligne à 21 lignes. (Antarctique, de la Jamaïque, etc.)

comment cela se fait? Quelle est l'approche la plus rapide ou la plus courante pour la recherche en direct et la mise à jour d'un objet de liste fournie XML?

Était-ce utile?

La solution

Personnellement, sauf si vous avez une raison de garder vos données xml, je transformerait la liste xml dans un ArrayCollection d'objets en premier. Si vous le faites lorsque vous chargez les données, il devrait vous donner une meilleure performance globale, en particulier avec des ensembles de données plus importants.

Mais pour répondre à votre question, je voudrais faire quelque chose comme ceci:. (Ceci suppose que transformer les données XML dans un ArrayCollection appelé _acData et vous avez un autre ArrayCollection appelé _acFilteredData qui est ce que le contrôle de liste est lié à Une fois que vous chargez les données en _acData, copiez-le dans _acFilteredData puis attachez une fonction comme celui-ci à votre saisie de texte)

private function inpFilter_change ( e:Event ) : void
{
    var searchString:String = StringUtil.trim(inpFilter.text).toLowerCase();

    if ( searchString.length )
    {
        var newAC:ArrayCollection = new ArrayCollection();

        for each ( var tempObject:Object in _acData)
        {
            if ( tempObject.countryName.toString().indexOf(searchString) != -1 )
            {
                newAC.addItem(tempObject);
            }
        }

        _acFilteredData = newAC;

        listControl.dispatchEvent(new ListEvent(ListEvent.CHANGE)); //might not be necessary, but will force the control to update  
    }
    else
    {
        _acFilteredData = _acData;
    }

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top