ActionScript - Оперативный поиск и обновление списка поставщиков данных?
-
08-10-2019 - |
Вопрос
я хочу добавить поиск в реальном времени в список, поставщиком данных которого является очень большой 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;
}
}