#apache-flex #components #arraycollection #filterfunction
#apache-flex #Компоненты #arraycollection #функция фильтрации
Вопрос:
У меня есть основное приложение, которое использует два экземпляра пользовательского компонента MXML DropDownList.
Я включил всю логику и запросы в пользовательский компонент для запроса MySQL и заполнения ArrayCollection результатом.
В моем первом выпадающем списке я хочу показать все доступные валюты, доступные в моей базе данных.
Во втором выпадающем списке я хочу показать валюты CAD и USD только с использованием функции фильтрации.
Я не знаю почему, но как только filterFunction применяется к первому элементу, второй действует так, как будто они используют одну и ту же переменную currenciesList (это МОЯ ПРОБЛЕМА).
[Bindable] для currenciesList требуется привязка к моему aSyncListView.
для использования в основном приложении требуетсяобщедоступный для currenciesList.
И независимо от того, является ли моя переменная общедоступной или частной, у меня одна и та же ошибка… Пожалуйста, просмотрите выходные данные в конце этого сообщения.
Вызов в моем основном приложении выглядит следующим образом :
<mx:Form>
<formElems:DropDownListCurrencies id="product_cost_price_curr"
currencyCadUsdOnly="true"/>
<formElems:DropDownListCurrencies id="product_price_curr"/>
</mx:Form>
Теперь мой пользовательский компонент :
<fx:Script>
<![CDATA[
import classes.SharedFunctions;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.events.FlexEvent;
import mx.rpc.events.ResultEvent;
[Bindable]
public var currenciesList:ArrayCollection;
public var currencyCadUsdOnly:Boolean = false;
protected function dropdownlist1_creationCompleteHandler(event:FlexEvent):void
{
getAllCurrenciesResult.token = currenciesService.getAllCurrencies();
// DEBUG just to show the id of the component
trace('id:' this.id ' (getAllCurrencies)');
}
protected function getAllCurrenciesResult_resultHandler(event:ResultEvent):void
{
currenciesList = getAllCurrenciesResult.lastResult;
// DEBUG before filterFunction
trace('id:' this.id ', currencyCadUsdOnly:' currencyCadUsdOnly ', currenciesList.length:' currenciesList.length ' (BEFORE filterFunction)');
if (currencyCadUsdOnly == true) {
currenciesList.filterFunction = filterCadUsdOnly;
currenciesList.refresh();
}
// DEBUG after filterFunction
trace('id:' this.id ', currencyCadUsdOnly:' currencyCadUsdOnly ', currenciesList.length:' currenciesList.length ' (AFTER filterFunction)');
}
protected function filterCadUsdOnly(obj:Object):Boolean
{
return (obj.code == 'CAD' || obj.code == 'USD');
}
]]>
</fx:Script>
<fx:Declarations>
<s:CallResponder id="getAllCurrenciesResult" result="getAllCurrenciesResult_resultHandler(event)"/>
<currenciesservice:CurrenciesService id="currenciesService" fault="SharedFunctions.showError(event.fault.faultString, event.fault.faultDetail)" showBusyCursor="true"/>
</fx:Declarations>
<s:AsyncListView list="{currenciesList}"/>
Наконец, давайте посмотрим на вывод консоли. Я ожидаю, что список массивов будет иметь длину 7 при создании второго компонента … :
id:product_prices_curr (getAllCurrencies)
id:product_cost_price_curr (getAllCurrencies)
id:product_prices_curr, currencyCadUsdOnly:true, currenciesList.length:7 (BEFORE filterFunction)
id:product_prices_curr, currencyCadUsdOnly:true, currenciesList.length:2 (AFTER filterFunction)
id:product_cost_price_curr, currencyCadUsdOnly:false, currenciesList.length:2 (BEFORE filterFunction)
id:product_cost_price_curr, currencyCadUsdOnly:false, currenciesList.length:2 (AFTER filterFunction)
СПАСИБО ЗА ПОМОЩЬ!
Ответ №1:
Всякий раз, когда вам нужно иметь один и тот же список в нескольких местах с разными фильтрами, вам нужен ListCollectionView. Таким образом, вы можете применить фильтр к нему, и вы не повлияете на исходный список. Это так же просто, как:
var secondList:ListCollectionView = new ListCollectionView(originalList);
И ваш secondList
может иметь любой фильтр, который вам нравится, не влияя на исходный список, с дополнительным преимуществом обновления при добавлении или удалении элементов из originalList
.
Смотрите здесь: mx.collections.ListCollectionView
Комментарии:
1. большое спасибо за это. Я значительно упрощаю объявление этой частной коллекции ListViewCollection в моем компоненте. Работает просто великолепно!
Ответ №2:
Попробуйте изменить свой код следующим образом:
if (currencyCadUsdOnly == true) {
currenciesList = new ArrayCollection(currenciesList.source);
currenciesList.filterFunction = filterCadUsdOnly;
currenciesList.refresh();
}
Надеюсь, это поможет!