Aufgabenstellung
Es wird eine Datenstruktur benötigt, die mehrere FilterFunctions unterstützt und mit der mx:ArrayCollection kompatibel ist.
Problem
mx:ArrayCollection besitzt nur die Eigenschaft für eine einzige Filter-Funktion. Möchte man mehrere Filter setzen, muss man komplexe Funktionen mit Filter-Logik implementieren.
Ansatz
Durch die Erweiterung der mx:ArrayCollection wird eine Methode filterFunctions implementiert, welche mehrere Filter entgegennehmen kann. Die erweiterte BjoernsArrayCollection kann in ArrayCollection gecastet oder ggfs. (z.B. durch eine Schleife) befüllt werden.
Lösung
Folgende Klasse erweritert die normale ArrayCollection um mehrere Filter-Funktionen:
package components { import mx.collections.ArrayCollection; public class BjoernsArrayCollection extends ArrayCollection { private var _filterFunctions:Array; public function BjoernsArrayCollection( source:Array = null ) { super(source); } public function set filterFunctions( filtersArray:Array ):void { _filterFunctions = filtersArray; this.filterFunction = complexFilter; } public function get filterFunctions():Array { return _filterFunctions; } protected function complexFilter( item:Object ):Boolean { var filterFlag:Boolean = true; var filter:Function; for each(filter in filterFunctions) { filterFlag = filter( item ); if( !filterFlag ) break; } return filterFlag; } } }
Der Filterfunktionen werden so deklariert:
// Result-Methode von Service liefert eine mx:ArrayCollection, die // anhand mehrerer Kriterien gefiltert wird. public function getResetableOrganizationsHandler(event:ResultEvent):void { // Instanzieren des neuen Objektes resetableorgas = new BjoernsArrayCollection(); // Deklaration der Filter resetableorgas.filterFunctions = [ filterByProductGroup, filterByCompcode, filterBySalesdiv, filterByMarket ]; // Umsortierung in BjoernsArrayCollection resetableorgas.removeAll(); for each(var item:ResetableOrganizationsVO in event.result) { resetableorgas.addItem(item); } resetableorgas.refresh(); }
Der Aufbau der Filter-Funktion:
... // Rückgabe ist true wenn der Vergleich des Eingegebenen (txtCompcode.text) // mit einem Element der ArrayCollection (item.compcode) passt private function filterByCompcode( item:Object ):Boolean { if( String(item.compcode).indexOf(txtCompcode.text)>-1 )return true; return false; } ...
Ggfs. (z.B. in einem mx:TextInput) die Refresh-Methode aufrufen:
<mx:TextInput change="{resetableorgas.refresh()}" id="txtCompcode" width="100%"/>