Pregunta

Quiero añadir la búsqueda en vivo a una lista cuyo proveedor de datos es una gran XML. por simplicidad, supongamos que mi XML es sólo una lista de los países del mundo 180ish:

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

labelFields de la lista están ocupados por <countryName> del elemento XML y en orden alfabético.

Me gustaría crear un campo de texto de entrada que va a escuchar a las pulsaciones de teclado y actualizar la lista de acuerdo a la cadena de entrada a juego los valores de los elementos del País. Por lo tanto, si entro "puede" en el campo de texto, la lista de repente será reducido a sólo 5 filas:

  • Samoa Americana
  • Canadá
  • República Centroafricana
  • República Dominicana
  • Ciudad del Vaticano

Por supuesto, búsqueda en tiempo real debe ser no destructiva, así - pulse borrar una vez por lo que el campo de búsqueda ahora se lee "ca", lo que aumenta la lista de 5 a 21 filas consecutivas. (Antártida, Jamaica, etc.)

¿Cómo se hace esto? lo que es el enfoque más rápida o la más común para la búsqueda en vivo y actualizar una lista XML proporcionado objeto?

¿Fue útil?

Solución

En lo personal, a menos que tenga una razón para mantener sus datos como XML, que transformaría la lista XML en un ArrayCollection de objetos en primer lugar. Si lo hace cuando se cargan los datos que debería darle un poco mejor rendimiento general, especialmente con grandes conjuntos de datos.

Pero para responder a su pregunta, me gustaría hacer algo como esto:. (Esto supone transformar los datos XML en un ArrayCollection llamada _acData y tiene otro ArrayCollection llamada _acFilteredData que es lo que el control de la lista está obligado a Una vez que carga hasta los datos en _acData, copiarlo en _acFilteredData y luego adjuntar una función como esta a la entrada de texto)

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

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