Arbeider med Flex DataGrid og Nested Data Structures

Det skjer ofte at dataene som må vises / presenteres i en Flex DataGrid kommer fra en XML-fil eller JSON med mer enn ett nestnivå. Dessverre kan Flex DataGrid som standard kun vise enkeltsidede nestede objektarrayer.

Denne opplæringen viser hvordan du kan utvide Flex DataGrid-klassen for å imøtekomme mer kompliserte datastrukturer. Det vil også vise deg hvordan du kan sortere alle kolonnene, selv når du bruker nestede datastrukturer.




Introduksjon

Denne opplæringen antar at du kjenner grunnlaget for Flex, hvordan du bruker Flex Builder, og hvordan du skriver MXML-filer. Du bør ha en kopi av Flex Builder installert på systemet ditt.

Trinn 1: Konfigurer Flex-prosjektet

Det første trinnet er å sette opp prosjektet i Flex Builder. Lag et nytt prosjekt i Flex Builder med prosjektnavn som "NestedDataGrid" og Applikasjonstype som "Webapplikasjon (kjører i Flash Player)". La alle andre alternativer stå til standardverdiene og klikk på Fullfør.

Trinn 2: Importer eksempeldata

Dataene som vi skal vise i DataGrid er hentet fra en XML-fil. Opprett en mappe i mappen 'src' kalt 'eiendeler' og legg dataene som er vist nedenfor i en fil som heter 'meetings.xml'. Alternativt kan du laste ned XML-filen herfra og sette den i mappen "eiendeler".

    høy  Lisa Green [email protected] +330-7593  12. juli 2009  Rom 405   medium  Christopher Martin [email protected] +330-7553  14. juli 2009  Rom 405   høy  George Rodriguez [email protected] +330-7502  18. juli 2009  Rom 771   høy  Jennifer Parker [email protected] +330-5380  20. august 2009  Rom 562  

Trinn 3: Gjør grensesnittet

Her er en rask nedbryting av å bygge grensesnittet for å vise dataene og de aktuelle ID-verdiene som kreves for koden i denne opplæringen:

  1. Åpne filen NestedDataGrid.mxml, og gå til designvisningen
  2. Dra og slipp et "Panel" fra komponentvisningen. Sett sin ID til "meetingsPanel" og Tittel til "Møter"
  3. Still høyden og bredden på panelet til 500 og still inn X- og Y-verdiene til 0
  4. Dra og slipp en "DataGrid" på panelet
  5. Sett X- og Y-verdiene til 10
  6. Still bredden til meetingsPanel.width-40 og høyde til 45%
  7. Gå til kildevisningen, og i attributten Mx: Appication, legg til attributtlayout = "vertikal"

Grensesnittet ditt bør se ut som det som vises i bildet nedenfor:

MXML i kildevisningen bør se slik ut:

            

Lese i XML-filen

I de neste tre trinnene oppretter vi en HTTPService-komponent, leser dataene fra XML-filen og lagrer den i en lokal variabel. Dette gjøres i tre faser:

Trinn 4: Opprett HTTPService-komponenten

Bytt til kildevisningen til MXML-filen og legg til følgende kode rett under mx: Søknad stikkord:

 

Funksjonen httpResultHandler () kalles når dataene er hentet. Hvis det oppstår en feil ved henting av data, kalles funksjonen httpFaultHandler (). Merk at dette bare oppretter HTTPService-objektet, dataene må hentes av et eksplisitt funksjonsanrop (se underpunkt 3)

Trinn 5: httpResultHandler () og httpFaultHandler ()

Legg til en mx: Script merk like under mx: Søknad stikkord. Inne i det, definer variabelen som vil holde innkommende data og funksjonene for å håndtere hendelsene fra HTTPService-komponenten. Koden for å gjøre det ser slik ut:

 importer mx.rpc.events.FaultEvent; importere mx.rpc.events.ResultEvent; importere mx.collections.ArrayCollection; importere mx.controls.Alert; [Bindable] public var dataForGrid: ArrayCollection; privat funksjon httpResultHandler (event: ResultEvent): void dataForGrid = event.result.meetings.meeting;  privat funksjon httpFaultHandler (event: FaultEvent): void Alert.show ("Feil oppstod ved å få streng"); 

Variabelen 'dataForGrid' inneholder dataene vi skal lese inn. '[Bindable]' -taggen sikrer at når dataene endres (når det leses inn), oppdateres DataGrid tilsvarende. XML leses inn som et objekt som sendes gjennom 'ResultEvent'-hendelsen, og' event.result.meetings.meeting 'åpner ArrayCollection av' møte 'objekter.

Trinn 6: Hent dataene fra XML-filen

I dette trinnet blir den faktiske funksjonskallet for å få XML-dataene gjort. En intialiseringsfunksjon er tilordnet hendelsen som utløses hver gang programmet laster - 'creationComplete' -hendelsen. Legg til attributtet creationComplete = "GetData ()" til 'mx: Application' -taggen og definer funksjonen 'getData ()' som nedenfor (som skal legges etter 'httpFaultHandler'-funksjonen):

 privat funksjon getData (): void readXML.send (); 

Dette gjør at HTTPService-objektet får dataene fra filen. Når dataene er hentet, utløses «resultatet» -hendelsen som kalles 'httpResultHandler ()' -funksjonen. Hvis det oppstår et problem med å få dataene, utløses "feil" -hendelsen, som kaller funksjonen httpFaultHandler ().

Trinn 7: Milestone

På dette tidspunktet bør din NestedDataGrid.mxml se slik ut:

                

Trinn 8: DataGrid med ikke-nestede data

Jeg vil bare kort påpeke hvorfor nestede data utgjør problemer i displayet, ved først å demonstrere hvordan du viser ikke-nestede data. Si, fra XML-filen ovenfor, ønsket du bare å vise dato, sted og prioritet for møtene (og ikke presentasjonsinformasjonen). Koden nedenfor vil kunne vise den uten problemer (innholdet av 'mx: Panel' vist her. All annen kode er den samme):

        

Resultatet av dette ville være følgende søknad:


Vær oppmerksom på at dataProvider-attributtet til DataGrid kan tildeles direkte til ArrayCollection 'dataForGrid', og hver DataGridColumn innsiden er gitt et dataField-attributt som direkte tilsvarer eiendomsnavnet. Anta at du vil få tilgang til presentatørens navninformasjon, men det kan nås som "presentatornavn". Hvis du prøver å gi denne verdien til 'dataField', får du en feil. Dette skyldes at Flex ikke støtter nestede gjenstander som standard. Les videre for å lære å løse dette problemet ved å utvide klassen DataGridColumn og skrive din egen kode for å håndtere denne saken.

Trinn 9: Opprette NestedDataGridColumn Class

Vi omdefinerer noen funksjoner i DataGrid-kolonneklassen for å omgå problemet beskrevet ovenfor. Først opprett en mappe i 'src' katalogen kalt 'klasser'. Opprett en ny 'ActionScript Class' i den mappen, kalt "NestedDataGridColumn". I feltet "Superclass" klikker du på "Bla gjennom ..." og velg "DataGridColumn" fra listen som dukker opp. La alt annet gå til standardverdiene, og klikk på "Fullfør". En ny fil skal ha blitt opprettet og befolket med følgende kode:

 pakke klasser import mx.controls.dataGridClasses.DataGridColumn; offentlig klasse NestedDataGridColumn utvider DataGridColumn offentlig funksjon NestedDataGridColumn (columnName: String = null) super (columnName); 

Trinn 10: Deklarer egenskapen 'nestedDataField'

I klassen NestedDataGridColumn legger du til en offentlig bindbar variabel kalt 'nestedDataField'. Vi bruker dette i stedet for standard 'dataField' -egenskapen til å sende feltnavnet. Dette er viktig, fordi hvis standardverdien 'dataField' er brukt, en feilmelding Feil: Finn kriterier må inneholde minst en sorteringsfeltverdi. vil oppstå når vi prøver å sortere DataGrid etter å ha definert den tilpassede sorteringsfunksjonen senere.

Trinn 11: Omdefinere 'itemToLabel' Funtion

Som du kan se, har den nye klassen vi opprettet allerede blitt befolket med en konstruktør. La konstruktøren være som den er og under som legger til følgende funksjon:

 overstyre offentlig funksjon itemToLabel (data: Object): String var felt: Array; Var-etikett: String; var dataFieldSplit: String = nestedDataField; var currentData: Objekt = data; // Sjekk om nestedDataField-verdien inneholder en '.' (dvs. å få tilgang til en nestet verdi) hvis (nestedDataField.indexOf (".")! = -1) // få alle feltene som må åpnes felt = dataFieldSplit.split ("."); for hver (var f: String i felt) // loop gjennom feltene en etter en og få den endelige verdien, går ett felt dypt hver iterasjon currentData = currentData [f]; hvis (currentData er String) // returnere den endelige verdien tilbake String (currentData);  // hvis det ikke er noen nesting involvert ellers if (dataFieldSplit! = "") currentData = currentData [dataFieldSplit];  // Hvis metoden vår ikke har virket som forventet, må du bruke standardfunksjonen til å prøve label = currentData.toString ();  fangst (e: Feil) label = super.itemToLabel (data);  // returnere resultat retur etiketten; 

Omdefinere funksjonen 'itemToLabel' er nøkkelen til å kunne få tilgang til nestede data i DataGrid. Funksjonen ItemToLabel styrer hva som vises i DataGrid-radene. Så vi bruker det her for å spørre Flex for å vise nestede data på den måten vi har spesifisert.

Som du kan se, begynner funksjonsdefinisjonen med søkeordet "override", som betyr at standard forhåndsdefinert funksjon med samme navn overstyres til fordel for funksjonen du har definert. Hver uttalelse er forklart i kommentarene. Kort sagt, hva funksjonen gjør er å kontrollere om nestede datafelt er tilgjengelig (hvis en '.' Er tilstede). Hvis det er, få hvert datafelt navn og iterate gjennom data Provider, gå dypere hvert trinn ved å gå til barnefeltet.

Funksjonen 'itemToLabel' kalles av Flex med et argument som inneholder ArrayCollection som ble spesifisert som dataProvider til dataGrid. Alle attributter av NestedDataGridColumn (når den brukes i mxml-filen) er direkte tilgjengelig, og eventuelle offentlige egenskaper definert i denne klassen kan tildeles en verdi i MXML. I vår NestedDataGrid.mxml-fil erstatter vi komponentene 'mx: DataGridColumn' med 'classes: NestedDataGridColumn'-komponenten og tilordner de spesifikke elementene som vi vil vise i kolonnene til' nestedDataField '-attributtet (som ble deklarert i' NestedDataGridColumn.as 'fil). DataGridColumn nå skal se slik ut:

          

Vær oppmerksom på at jeg direkte angir egenskapen 'nestedDataField' som «presentatornavn» og «presentator.telefon» her. Jeg har også lagt til bredder i kolonnene og satt bredden på komponenten 'mx: Panel' til 600px for bedre visning. Jeg har lagt til «sorterbar» egenskapen for å være falsk for de to nye kolonnene. Hvis du fjerner dette (eller setter det til sant) og kjører programmet, vil kolonnen ikke sortere. Vi løser dette i neste trinn ved å definere vår egen sorteringsfunksjon. For nå bør søknaden se slik ut:


Trinn 12: Skrive den egendefinerte sorteringsfunksjonen

Det eneste som igjen er å definere den egendefinerte sorteringsfunksjonen, slik at sorteringen også vil bli aktivert i alle feltene (si, du vil sortere presentatørnavnene alfabetisk). Legg til funksjonen kalt 'mySortCompareFunction' under funksjonen 'itemToLabel' som gitt:

 privat funksjon mySortCompareFunction (obj1: Objekt, obj2: Objekt): int var felt: Array; var dataFieldSplit: String = nestedDataField; var currentData1: Objekt = obj1; var currentData2: Objekt = obj2; hvis (nestedDataField.indexOf (".")! = -1) felt = dataFieldSplit.split ("."); for hver (var f: String i felt) currentData1 = currentData1 [f]; currentData2 = currentData2 [f];  else if (dataFieldSplit! = "") currentData1 = currentData1 [dataFieldSplit]; currentData2 = currentData2 [dataFieldSplit];  hvis (currentData1 er int && currentData2 er int) var int1: int = int (currentData1); var int2: int = int (currentData2); var resultat: int = (int1> int2)? - 1: 1; returresultat;  hvis (currentData1 er String && currentData2 er String) currentData1 = String (currentData1); currentData2 = String (currentData2); returnere (currentData1> currentData2)? - 1: 1;  hvis (currentData1 er Date && currentData2 er Date) var date1: Date = currentData1 som Date; var date2: Date = currentData2 som Date; var date1Timestamp: Number = currentData1.getTime (); var date2Timestamp: Number = currentData2.getTime (); returnere (date1Timestamp> date2Timestamp)? - 1: 1;  returnere 0; 

Denne funksjonen kalles av Flex med to objekter, og det forventes å returnere enten -1,0 eller 1 avhengig av om det første objektet er større enn, lik eller mindre enn henholdsvis den andre objektet. Flex tar seg av den faktiske sorteringen.

Denne funksjonen bruker samme logikk som 'itemToLabel' -funksjonen for å få den aktuelle nestede verdien. Da avhenger av typen av verdien (om den er int, String eller Date), sammenligner den den på riktig måte, og returnerer -1 hvis 'currentData1' er større enn 'currentData2', 0 hvis de er like og 1 hvis 'currentData2 'er større enn' currentData1 '.

Trinn 13: Tilkobling av tilpasset sorteringsfunksjon

Hvis du la merke til, er 'customSortCompareFunction' ikke en forhåndsdefinert funksjon i klassen DataGridColumn som vi tilsidesetter. Denne funksjonen må tilordnes som sorteringsfunksjonen på en annen måte. Vi må tilordne den forhåndsdefinerte variabelen 'sortCompareFunction' navnet på sorteringsfunksjonen, som er 'customSortCompareFunction' i vårt tilfelle. Dette skal gjøres inne i konstruktøren. Konstruktøren ser nå slik ut:

 offentlig funksjon NestedDataGridColumn (columnName: String = null) // den tilpassede sorteringsfunksjonen tilordnes den forhåndsdefinerte variabelen sortCompareFunction = mySortCompareFunction; super (Kolonne); 

Når dette er gjort, er du helt klar. Du har nå en egendefinert klasse som kan håndtere vilkårlig nestede data som skal vises i en DataGrid. Og du kan sortere rutenettet som du vil.

Konklusjon

I dag lærte du å omgå en begrensning av FlexDataGrid-klassen for å få vilkårlig nestede data, og vise den i en DataGrid. Du lærte også hvordan du definerer din egen sorteringsfunksjon, slik at rutenettet fortsatt kan sorteres. Du kan nå bruke denne NestedDataGridColumn i alle dine applikasjoner uten overhead.

Du kan videre utvide funksjonen "itemToLabel" for å inkludere andre vilkårlige tilgangsformer - si, få tilgang til arrayer i barnobjektene, eller få tilgang til xml-attributter. Du kan også utvide sorteringsfunksjonen for å sortere andre typer data. Du kan også legge til andre funksjoner som å fargelegge radene basert på møteprioritet og vise flere detaljer om presentatøren ved å klikke på en rad.

Takk for at du leste :)