Zurück   Flashforum > Flex und AIR > Flex programmieren

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 13-11-2011, 12:49   #1 (permalink)
Neuer User
 
Registriert seit: Dec 2001
Beiträge: 114
Question komplexe dynamische filterfunction für arraycollection

hallo experten,
ich habe eine ArrayCollection in der viele Einträge der Klasse Zeitstempel gespeichert sind. So ein Zeitstempel besteht aus einer Mitarbeiter_id, einer aufgaben_id, einer Startzeit und einer Endzeit. Jeder Mitarbeiter erstellt also jedesmal wenn er an einer bestimmten Aufgabe gearbeitet hat einen neuen Zeitstempel der festhält von wann bis wann er daran gearbeitet hat.

Diese ArrayCollection möchte ich nun auf verschiedene Arten auswerten und mit Charting-Komponenten darstellen.

Ein Beispiel:
Ein Kuchen-Chart soll darstellen wie lange insgesamt an dem gesamten Projekt gearbeitet wurde (also die Summe der Dauer aller Zeitstempel) und gleichzeitig welcher Mitarbeiter welchen Gesamtanteil daran hat (also die Summe der Dauer aller Zeitstempel die von den jeweiligen Mitarbeiter erstellt wurden)

Ich könnte derartige Abfragen natürlcih direkt auf meiner MySql Datenbank (von der die Daten stammen) machen und dann in Flex darstellen, allerdings würde ich mir diesen Traffic gerne sparen denn eigentlich sind ja alle Daten die ich benötige schon in der ZeitstempelArrayCollection beim Client vorhanden.
Leider kriege ich es nicht hin die filterFunction der ArrayCollection so dynamisch zum Einsatz zu bringen.
Problem verstanden?Kann und möchte mir jemand helfen?
Danke
arnold85 ist offline   Mit Zitat antworten
Alt 13-11-2011, 13:05   #2 (permalink)
Perverted Hermit
 
Benutzerbild von Omega Psi
 
Registriert seit: Mar 2004
Ort: Bremen
Beiträge: 13.382
Was hast du denn schon?
Omega Psi ist offline   Mit Zitat antworten
Alt 13-11-2011, 16:13   #3 (permalink)
Neuer User
 
Registriert seit: Dec 2001
Beiträge: 114
Also nach meinem letzten Eintrag haben ich mir noch folgendes "zusammengewurschtelt":
Code:
private function prepareDataForDisplayAllMitarbeiterCompleteWork(ac_data:ArrayCollection):ArrayCollection
			{
				var ac_tempAlleZeitstempel:ArrayCollection=new ArrayCollection();
				ac_tempAlleZeitstempel.addAll(ac_data);
				var ac_zeitstempelGeteiltNachMitarbeitern:ArrayCollection= new ArrayCollection();
				for each (var tempMitarbeiter:Mitarbeiter in ac_allMitarbeiter)
				{
					
					var filtered_array:Array = FilterByProperty(ac_tempAlleZeitstempel.source, tempMitarbeiter.idmitarbeiter);
					var ac_alleZeitstempelEinesMitarbeiters:ArrayCollection=new ArrayCollection(filtered_array);
					ac_zeitstempelGeteiltNachMitarbeitern.addItem(ac_alleZeitstempelEinesMitarbeiters);
				}
				return ac_zeitstempelGeteiltNachMitarbeitern;
			}
			protected function FilterByProperty(input_array:Array, extra_testing:Object):Array
			{
				function FilterFunction(element:Object, index:int, array:Array):Boolean
				{
					return element.mitarbeiter_idmitarbeiter == extra_testing; 
				}
				
				return input_array.filter(FilterFunction);
			}
funktioniert auch soweit, dass ich am Ende schon mal eine ArrayCollection habe welche wiederum für jeden Mitarbeiter eine weitere ArrayCollection enthält in der dann alle zeitstempel des jeweiligen mitarbeiter enthalten sind. Diese müsste ich dann alle nochmal durchlaufen und die dauer der jeweiligen zeitstempel zusammenrechnen.
Aber alles sehr umständlich und unschön finde ich.
Vielleicht geht es ja doch viel einfacher!?
arnold85 ist offline   Mit Zitat antworten
Alt 13-11-2011, 16:44   #4 (permalink)
Perverted Hermit
 
Benutzerbild von Omega Psi
 
Registriert seit: Mar 2004
Ort: Bremen
Beiträge: 13.382
Ja, ich verstehe deinen Code nicht so ganz ... die Idee hinter meinem Code:
  1. nur eine Collection, die gefiltert wird.
  2. eine Filter-Funktion, die darauf angewandt wird.
Code:
package org.icodeapps.filters
{
  import mx.collections.ICollectionView;

  public class FilterStrategy
  {
    //-------------------------------------------------------------------------
    //
    //          Properties
    //
    //-------------------------------------------------------------------------

    //---------------------------------
    //          collection
    //---------------------------------

    private var _collection:ICollectionView;

    function set collection(value:ICollectionView):void
    {
      if (_collection)
      {
        _collection.filterFunction = null;
      }

      _collection = value;

      if (_collection)
      {
        updateFilterFunction();
        refreshCollection();
      }
    }

    //---------------------------------
    //          enableFiltering
    //---------------------------------

    private var _enableFiltering:Boolean;

    public function set enableFiltering(value:Boolean):void
    {
      _enableFiltering = value;
      if (_collection)
      {
        updateFilterFunction();
        refreshCollection();
      }
    }

    //---------------------------------
    //          filterForName
    //---------------------------------

    private var _filterForName:Boolean;

    public function set filterForName(value:Boolean):void
    {
      _filterForName = value;
      refreshCollection();
    }

    //---------------------------------
    //          name
    //---------------------------------

    private var _name:String;

    public function set name(value:String):void
    {
      _name = value;
      refreshCollection();
    }

    private function refreshCollection():void
    {
      if (!_collection) return;

      _collection.refresh();
    }

    //-------------------------------------------------------------------------
    //
    //          Methods
    //
    //-------------------------------------------------------------------------

    private function filter(item:Object):Boolean
    {
      if (!_enableFiltering) return true;

      if (!item) return false;

      if (_filterForName && item.property('name') && item['name'] != _name) return false;

      return true;
    }

    private function updateFilterFunction():void
    {
      _collection.filterFunction = _enableFiltering ? filter : null;
    }
  }
}
Du kannst einfach die Filter-Funktion und die Klasse nach deinen Belieben anpassen. Meine Vorschäge:
  1. Für jede Collection einen andere Strategie.
  2. filter sollte einen kokreten Datentypen bekommen, um den Code zu vereinfachen.
  3. Man kann auch mehrere Subroutinen implementieren und die dann über die Setter in ein Array stecken/entfernen, das dann in der Filterfunktion durchlaufen wird, um das Objekt entsprechend den gesetzten Filtern zu validieren.
Omega Psi ist offline   Mit Zitat antworten
Alt 13-11-2011, 17:22   #5 (permalink)
Neuer User
 
Registriert seit: Dec 2001
Beiträge: 114
Thumbs up

das gefällt mir sehr gut. Damit werde ich es mal versuchen udn mich dann zurück melden.
Tausend Dank und ich bin mal wieder beeindruckt mit welcher Einsatzfreude du dich an die Probleme anderer machst und da du wirklich "Clean Code" hast, dient dein Code auch schon gut als Tutorial.

schönen abend noch
arnold85 ist offline   Mit Zitat antworten
Alt 23-11-2011, 10:44   #6 (permalink)
Neuer User
 
Benutzerbild von LordCorax
 
Registriert seit: Nov 2007
Ort: Göttingen
Beiträge: 151
Moin moin,

die Variante ist auch nicht schlecht. Ich hab mich allerdings für eine andere entschieden. Hierzu hab ich mir eine BasicVO-Klasse geschrieben, die von den anderen ValueObject-Klassen geerbt wird.

So sieht die Basic-Klasse aus:

PHP-Code:
package vo 
{
    
import mx.utils.ObjectUtil;

    public class 
BasicVO 
    
{
        private var 
properties:Array = new Array();
        
        public function 
BasicVO() 
        {
            
properties listProperties(this);
        }
        private function 
listProperties(item:Object):Array 
        {
            var 
obj:Object ObjectUtil.getClassInfo(item);
            var 
arr:Array = obj.properties as Array;
            return 
arr;
        }
        public function 
search(item:String):Boolean
        
{
            var 
isObject:Boolean false;
            var 
searchString:String = new String();
            for (var 
i:int 0properties.lengthi++) 
            {
                
searchString this[properties[i]];
                if (
searchString != null
                {
                    if (
searchString.toLowerCase().search(item.toLowerCase()) != -1
                    {
                        
isObject true;
                    }
                }
            }
            return 
isObject;
        }
    }


Und so eine erbende Klasse:
PHP-Code:
package vo 
{
    [
Bindable]
    public class 
PersonalVO extends BasicVO 
    
{
        public var 
vorname:String;
        public var 
nachname:String;
        public var 
titel:String;
        public var 
alter:int;
        public var 
geschlecht:String;
        
        public function 
PersonalVO(vorname:Stringnachname:Stringalter:inttitel:Stringgeschlecht:String
        {
            
super(); //Super-Statement nicht vergessen;
            
this.vorname vorname;
            
this.nachname nachname;
            
this.alter alter;
            
this.geschlecht geschlecht;
            
this.titel titel;
        }
    }


Jetzt kann man bspw. eine ArrayCollection in der Flex-Anwendung mit PersonalVO's füllen und diese mit einer Suchfunktion über mehrere Properties hinweg filtern. Siehe Beispiel:

PHP-Code:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="onInit();">
    
    <mx:Script>
        <![CDATA[
        import mx.collections.ArrayCollection;
        import vo.PersonalVO;
        [Bindable]
        private var personalCollection:ArrayCollection = new ArrayCollection();
        private function onInit():void
        {
            personalCollection.addItem(new PersonalVO("Peter", "Griffin", 35, "", "Männlich"));
            personalCollection.addItem(new PersonalVO("Glenn", "Quagmire", 33, "", "Männlich"));
            personalCollection.addItem(new PersonalVO("Joseph", "Swanson", 35, "", "Männlich"));            
        }
        public function filterPerson():void
        {
            personalCollection.filterFunction = searchVO;
            personalCollection.refresh();
        }
        private function searchVO(vo:PersonalVO):Boolean
        {
            var pvo:PersonalVO = vo;
            return pvo.search(suchFeld.text);
        }
        ]]>
    </mx:Script>
    <mx:DataGrid id="personalGrid" dataProvider="{personalCollection}">
        <mx:columns>
            <mx:DataGridColumn dataField="vorname" headerText="Vorname:"/>
            <mx:DataGridColumn dataField="nachname" headerText="Nachname:"/>
        </mx:columns>
    </mx:DataGrid>
    <mx:TextInput id="suchFeld" width="100" change="filterPerson();"/>
</mx:Application>
VG

LordCorax

Geändert von LordCorax (23-11-2011 um 10:46 Uhr)
LordCorax ist offline   Mit Zitat antworten
Alt 23-11-2011, 11:21   #7 (permalink)
Perverted Hermit
 
Benutzerbild von Omega Psi
 
Registriert seit: Mar 2004
Ort: Bremen
Beiträge: 13.382
Sehe ich das richtig und du schaust nur, ob ein VO eine Eigenschaft hat? Das schränkt die Usecases ja schon etwas ein.
Omega Psi ist offline   Mit Zitat antworten
Alt 23-11-2011, 11:52   #8 (permalink)
Neuer User
 
Benutzerbild von LordCorax
 
Registriert seit: Nov 2007
Ort: Göttingen
Beiträge: 151
Ja, das tue ich. An sich genügt mir die Variante auch vollkommen. Aber du hast recht, deine ist natürlich allumfassender.
LordCorax ist offline   Mit Zitat antworten
Alt 23-11-2011, 12:05   #9 (permalink)
Perverted Hermit
 
Benutzerbild von Omega Psi
 
Registriert seit: Mar 2004
Ort: Bremen
Beiträge: 13.382
Das war auch nicht böse gemeint, nur eine Feststellung
Omega Psi ist offline   Mit Zitat antworten
Alt 23-11-2011, 12:18   #10 (permalink)
Neuer User
 
Benutzerbild von LordCorax
 
Registriert seit: Nov 2007
Ort: Göttingen
Beiträge: 151
Hehe, ich dachte schon ich bekäme hier gleich einen vor den Bug geschossen wegen meines Ansatzes.
LordCorax ist offline   Mit Zitat antworten
Alt 23-11-2011, 12:22   #11 (permalink)
Perverted Hermit
 
Benutzerbild von Omega Psi
 
Registriert seit: Mar 2004
Ort: Bremen
Beiträge: 13.382
Nene, alles gut. Wenn es für dich funktioniert, ist das gut. Allgemein gültige Lösungen sind schwer zum implementieren. Thanx for the beitrag
Omega Psi ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Stichworte
arraycollection, dynamisch, filterfunction

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
ArrayCollection <-> Array Henning06 Flash CS4 Professional 1 15-08-2009 13:27
dynamische ArrayCollection verflext Flex programmieren 7 11-06-2009 21:24
arraycollection n82 Flex programmieren 8 04-03-2009 16:30
XML zu ArrayCollection zidaninho Flex programmieren 1 01-03-2009 17:13
hilfe!!komplexe dynamische webcam. hilfe!! ich_checks_net Flash 8 3 11-08-2008 10:39


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:24 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2014 Marc Thiele