У меня вопрос Flex, который не так прост, как кажется на первый взгляд.Объединить данные в фильтр ArrayCollection (возможно, с помощью IViewCursor или localIndex?)
По крайней мере, я боюсь с 1 недели с этим.
Я подготовил кейс и скриншот.
Вопрос: Как вы объедините данные (поступающие повторно с сервера) в отфильтрованный ArrayCollection?
Скриншот:
TestCase.mxml (просто поместите его в 4.6 проекта Flash Builder):
<?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">
<fx:Declarations>
<s:RadioButtonGroup id="_group" itemClick="radioClicked(event);"/>
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.events.ItemClickEvent;
[Bindable]
private var _data:ArrayCollection = new ArrayCollection();
private const DATA1:Array = [10,20,30,40,50];
private const DATA2:Array = [10,20,30,50];
private const DATA3:Array = [10,20,30,40,50,60];
private const DATA4:Array = [10,20,30,35,40,50];
private const DATA5:Array = [];
private const DATA6:Array = [25,45];
private function merge(data:Array):void {
var i:int;
var j:int;
// 1) remove items missing in data from _data
found1:
for (i = _data.length - 1; i >= 0; i--) {
for (j = data.length - 1; j >= 0; j--) {
if (_data[i] == data[j])
continue found1;
}
_data.removeItemAt(i);
}
// 2) add items appeared in data to _data
found2:
for (j = 0; j < data.length; j++) {
for (i = 0; i < _data.length; i++) {
if (_data[i] == data[j])
continue found2;
}
_data.addItem(data[j]);
}
}
private function radioClicked(event:ItemClickEvent):void {
if (event.label.indexOf('Odd') == 0) {
_data.filterFunction = filterOdd;
} else if (event.label.indexOf('Even') == 0) {
_data.filterFunction = filterEven;
} else {
_data.filterFunction = null;
}
_data.refresh();
}
private function filterOdd(item:Object):Boolean {
var i:uint = item as uint;
return (i % 2 == 1);
}
private function filterEven(item:Object):Boolean {
var i:uint = item as uint;
return (i % 2 == 0);
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout gap="20" />
</s:layout>
<s:HGroup verticalAlign="baseline">
<s:Label text="FILTER:" />
<s:RadioButton groupName="_group" label="All" selected="true" />
<s:RadioButton groupName="_group" label="Odd" />
<s:RadioButton groupName="_group" label="Even" />
</s:HGroup>
<s:List id="_list" dataProvider="{_data}" />
<s:Button id="_btn1" label="{DATA1.join()}" click="merge(DATA1)" />
<s:Button id="_btn2" label="{DATA2.join()}" click="merge(DATA2)" />
<s:Button id="_btn3" label="{DATA3.join()}" click="merge(DATA3)" />
<s:Button id="_btn4" label="{DATA4.join()}" click="merge(DATA4)" />
<s:Button id="_btn5" label="{DATA5.join()}" click="merge(DATA5)" />
<s:Button id="_btn6" label="{DATA6.join()}" click="merge(DATA6)" />
</s:Application>
Проблема заключается в том, что, когда ArrayCollection _data: отфильтрован (поскольку установлен флажок «Четный»), то второй цикл в тестовом примере (для добавления новых элементов) снова и снова добавляет элементы («35») потому что он фильтруется и, следовательно, не отображается.
Пожалуйста, предложите решение - с исходным кодом.
Пожалуйста, не отправляйте меня в такие документы, как IViewCursor или ListCollectionView.localIndex - потому что я прочитал их много на прошлой неделе.
Спасибо!
Прекрасный ответ, спасибо. Мне просто интересно, если getItemIndex() всегда будет работать даже для более сложных объектов, хранящихся в ArrayCollection? –
Насколько ActionScript работает с указателями на объекты, все указатели на один и тот же экземпляр равны. И 'ArrayCollection' просто сравнивает указатели на экземпляры сложных типов в' getItemIndex() '. Таким образом, он отлично подходит для сложных объектов. – Constantiner
Итак, если у меня есть ArrayCollection объектов XML в моем реальном приложении и вам нужно сравнить и