ActionScript - Оперативный поиск и обновление списка поставщиков данных?

StackOverflow https://stackoverflow.com/questions/4162924

Вопрос

я хочу добавить поиск в реальном времени в список, поставщиком данных которого является очень большой XML-файл.для простоты давайте предположим, что мой XML-файл - это всего лишь список из 180 стран мира:

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 списка заполняются значениями XML-элемента <countryName> и расположены в алфавитном порядке.

я хотел бы создать текстовое поле ввода, которое будет прослушивать нажатия клавиш и обновлять список в соответствии со строкой ввода, соответствующей значениям элемента countryName.поэтому, если я введу "can" в текстовое поле, список внезапно сократится всего до 5 строк:

  • Американское Самоа
  • Канада
  • Центральноафриканская Республика
  • Доминиканская Республика
  • Город Ватикан

конечно, поиск в реальном времени также должен быть неразрушающим - нажмите "Удалить" один раз, чтобы в поле поиска теперь было указано "ca", что увеличивает список из 5 строк до 21 строки.(Антарктида, Ямайка и др.)

как это делается?каков самый быстрый или наиболее распространенный подход к оперативному поиску и обновлению объекта списка, предоставленного в формате XML?

Это было полезно?

Решение

Лично я, если у вас нет причин сохранять свои данные в формате xml, сначала преобразовал бы xml-список в ArrayCollection объектов.Если вы сделаете это при загрузке данных, это должно повысить производительность в целом, особенно при использовании больших наборов данных.

Но чтобы ответить на ваш вопрос, я бы сделал что-то вроде этого:(это предполагает, что вы преобразуете xml-данные в ArrayCollection с именем _acData, и у вас есть другой ArrayCollection с именем _acFilteredData, к которому привязан элемент управления list.Как только вы загрузите данные в _acData, скопируйте их в _acFilteredData, а затем прикрепите подобную функцию к вашему текстовому вводу)

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

}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top