Arbeide med Flex Datagrid og Nøstet data Structures

Working med Flex Datagrid og Nøstet datastrukturer
to
Del
en
Del

Denne Cyber ​​Monday Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.

Det skjer ofte at data som må sees /presentert i en Flex Datagrid kommer fra en XML-fil eller JSON med mer enn ett nivå av hekkende. Dessverre, som standard, gjør at Flex Grid du å vise bare én nivå nestet objekt arrays.

Denne veiledningen viser hvordan du kan forlenge Flex Grid klassen å imøtekomme mer kompliserte datastrukturer. Det vil også vise deg hvordan du gjør alle kolonnene sorterbar, selv når du bruker nøstede datastrukturer.



Innledning

Denne opplæringen forutsetter at du vet det grunnleggende Flex, hvordan du bruker Flex Builder, og hvordan du skal skrive MXML filer. Du bør ha en kopi av Flex Builder installert på systemet ditt

Trinn 1:. Setup Flex Prosjekt

Det første trinnet er å sette prosjektet i Flex Builder. Opprett et nytt prosjekt i Flex Builder med Prosjektnavn
som "NestedDataGrid" og Application Skriv
som "web-applikasjon (kjører i Flash Player)". La alle andre alternativer på standardverdiene, og klikk på Fullfør

Trinn 2:. Import eksempeldata

De data som vi kommer til å vise i Datagrid er hentet fra en XML-fil. Lag en mappe i 'src' mappe kalt 'eiendeler "og sette dataene nedenfor i en fil som heter" meetings.xml'. Alternativt kan du laste ned XML-fil fra her og sette den i "eiendeler" -mappen
. ≪? Xml version = "1.0" encoding = "UTF-8" >? ≪ møter > < møte > < prioritet > høy < /prioritet > < programleder > < navn > Lisa Green < /navn > < e > [email protected]< /e > < telefon > + 330-7593 < /telefon > < /programleder > < date > 12 juli 2009 < /dato > < tid > 6: 00 < /tid > < sted > Room 405 < /sted > < /møte > < møte > < prioritet > medium < /prioritet > < programleder > < navn > Christopher Martin < /navn > < e > [email protected]< /e > < telefon > + 330-7553 < /telefon > < /programleder > < date > 14 juli 2009 < /dato > < tid > 11: 00 am < /tid > < sted > Room 405 < /sted > < /møte > < møte > < prioritet > høy < /prioritet > < programleder > < navn > George Rodriguez < /navn > < e > [email protected]< /e > < telefon > + 330-7502 < /telefon > < /programleder > < date > 18 juli 2009 < /dato > < tid > 10: 00 am < /tid > < sted > Room 771 < /sted > < /møte > < møte > < prioritet > høy < /prioritet > < programleder > < navn > Jennifer Parker < /navn > < e > [email protected]< /e > < telefon > + 330-5380 < /telefon > < /programleder > < date > 20 august 2009 < /dato > < tid > 2: 24:00 < /tid > < sted > Room 562 < /sted > < /møte > < /møter >
Trinn 3: Gjør Interface

Her er en rask oversikt over bygge grensesnittet for å vise dataene og de riktige ID-verdier som kreves for koden i denne opplæringen:


    Åpne NestedDataGrid.mxml filen, og gå til utformingsvisning

    Dra og slipp en "Panel" fra Components visningen. Sette sitt ID til "meetingsPanel" og tittel til "Meetings"

    Angi høyden og bredden på panelet til 500 og sette X og Y-verdiene til 0

    Dra og slipp en Datagrid 'på panelet

    Sett X og Y-verdiene til 10

    Sett bredden til {meetingsPanel.width-40} og høyden til 45%

    Gå til kilden visning, og i "mx: Påførings 'tag, legge til attributtet layout =" vertikal "

    Din grensesnittet skal se lik som vist på bildet under:

    MXML i kilde visningen skal se slik ut:?
    < xml version = "1.0" encoding = "UTF-8" > < mx:? Søknad xmlns: mx = "http://www.adobe.com /2006 /MXML "layout =" vertikal "> < mx: Panel x = "0" y = "0" width = "500" height = "500" layout = "absolutt" id = "meetingsPanel" title = "Meetings" > < mx: Datagrid x = "10" y = "10" width = "{meetingsPanel.width-40}" height = "45%" > < mx: kolonner > < mx: DataGridColumn headerText = "Kolonne en" datafeltet = "col1" /> < mx: DataGridColumn headerText = "Kolonne 2" datafeltet = "col2" /> < mx: DataGridColumn headerText = "Kolonne 3" datafeltet = "kol3" /> < /mx: kolonner > < /mx: Datagrid > < /mx: Panel > < /mx: Application >
    Lesing i XML File

    I de neste tre trinnene, skaper vi en HTTPService komponent, lese data fra XML-filen og lagre den i en lokal variabel. Dette gjøres i tre trinn:

    Trinn 4: Lag HTTPService Component

    Bytt til kilden visning av MXML fil og legge til følgende kode rett under mx: Søknad
    tag:
    < mx: HTTPService id = "readXML" url = "assets /meetings.xml" resultFormat = "objekt" resultat = "httpResultHandler (event)" feil = "httpFaultHandler (event)" />

    Den httpResultHandler () -funksjonen vil bli kalt når data har blitt hentet. Hvis det er en feil i henting av data, er httpFaultHandler () -funksjonen kalles. Merk at dette bare skaper HTTPService objekt, har data som skal hentes av en eksplisitt funksjon samtale (Se sub-trinn 3)

    Trinn 5: httpResultHandler () og httpFaultHandler ()

    Legg en mx: Script
    tag rett under mx: Søknad
    tag. Inne det, definere variabelen som vil holde de innkommende data og funksjoner for å håndtere hendelser fra HTTPService komponent. Koden for å gjøre det ser ut som dette:
    import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.collections.ArrayCollection; import mx.controls.Alert; [Bind] offentlig Var dataForGrid: ArrayCollection; privat funksjon httpResultHandler (event: ResultEvent): void {dataForGrid = event.result.meetings.meeting; } Private funksjon httpFaultHandler (event: FaultEvent): void {Alert.show ("Feil oppstått i å få strengen"); }

    Den variable 'dataForGrid' holder dataene som vi kommer til å lese i. "[bind] -kode gjør at når dataene endres (når den er lest i), er Datagrid oppdatert tilsvarende. XML, leses som et objekt som er gått trodde 'ResultEvent "hendelse, og' event.result.meetings.meeting 'aksesserer ArrayCollection av sine oppmøte' stedene.

    Trinn 6: Få data fra XML File

    I dette trinnet, selve funksjonskall for å få XML-data er gjort. En intialize funksjon legges til hendelsen som utløses hver gang programmet laster - den "creationComplete 'event. Legg attributtet creationComplete = "GetData ()"
    til "mx: Søknad 'tag og definere funksjonen' GetData () 'som nedenfor (for å bli lagt til etter den" httpFaultHandler' funksjon):
    privat funksjon GetData (): void {readXML.send (); }

    Dette gjør HTTPService objektet få data fra filen. Når dataene er hentet, er "resultatet" hendelse utløses som kaller 'httpResultHandler ()' funksjon. Hvis det er et problem å få dataene blir "feil" hendelsen utløste, som kaller httpFaultHandler () -funksjonen

    Trinn 7:. Milepæl

    På dette punktet ditt NestedDataGrid.mxml skal se ut dette:?
    < xml version = "1.0" encoding = "UTF-8" > < mx:? Søknad xmlns: mx = "http://www.adobe.com/2006/mxml" layout = "vertikal" creationComplete = "GetData ()" > < mx: Script > <! [CDATA [import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.collections.ArrayCollection; import mx.controls.Alert; [Bind] offentlig Var dataForGrid: ArrayCollection; privat funksjon httpResultHandler (event: ResultEvent): void {dataForGrid = new ArrayCollection (event.result.meetings.meeting); } Private funksjon httpFaultHandler (event: FaultEvent): void {Alert.show ("Feil oppstått i å få strengen"); } Private funksjon GetData (): void {readXML.send (); }]] ≫ < /mx: Script > < mx: HTTPService id = "readXML" url = "assets /meetings.xml" resultFormat = "objekt" resultat = "httpResultHandler (event)" feil = "httpFaultHandler (event)" /> < mx: Panel width = "500" height = "500" layout = "vertikal" id = "meetingsPanel" title = "Meetings" > < mx: Datagrid width = "{meetingsPanel.width-40}" height = "45%" > < mx: kolonner > < mx: DataGridColumn headerText = "Kolonne en" datafeltet = "col1" /> < mx: DataGridColumn headerText = "Kolonne 2" datafeltet = "col2" /> < mx: DataGridColumn headerText = "Kolonne 3" datafeltet = "kol3" /> < /mx: kolonner > < /mx: Datagrid > < /mx: Panel > < /mx: Application >
    Trinn 8: Datagrid med Non-Nøstet data

    Jeg vil bare kort påpeke hvorfor nestet data skaper problemer i displayet, ved først å demonstrere hvordan du viser ikke-nestet data. Si fra XML-filen ovenfor, du bare ønsket å vise dato, sted og prioritering av møtene (og ikke den som presenterer informasjon). The nedenfor koden vil være i stand til å vise det uten problemer (. Innholdet i 'mx: Panel' vises her er All annen kode det samme):
    < mx: Datagrid width = "{meetingsPanel.width-40}" height = "45%" dataprovider = "{dataForGrid}" > < mx: kolonner > < mx: DataGridColumn headerText = "Priority" datafeltet = "priority" /> < mx: DataGridColumn headerText = "Dato" datafeltet = "date" /> < mx: DataGridColumn headerText = "Time" datafeltet = "tid" /> < mx: DataGridColumn headerText = "Place" datafeltet = "sted" /> < /mx: kolonner > < /mx: Datagrid >

    Resultatet av dette vil være følgende program:

    Merk at dataprovider egenskap av Datagrid kan være direkte tilordnet den ArrayCollection 'dataForGrid', og hver DataGridColumn inne er gitt en datafeltet attributt som direkte tilsvarer eiendommen navn. Men antar at du vil ha tilgang til programleder navn informasjon, det kan nås som "presenter.name". Hvis du prøver å gi denne verdien til "datafeltet", vil du få en feilmelding. Dette er fordi, Flex ikke støtter kjedede gjenstander som standard. Les videre for å lære hvordan du kan løse dette problemet ved å utvide DataGridColumn klassen og skrive din egen kode for å håndtere denne saken

    Trinn 9:. Opprette NestedDataGridColumn Class

    Vi omdefinere enkelte funksjoner i Datagrid kolonne klasse for å omgå problemet skissert ovenfor. Først opprette en mappe i 'src' katalog som heter 'klasser'. Opprett en ny "Action Class 'i mappen som heter" NestedDataGridColumn ". I "superklassen feltet, klikk" Bla gjennom ... "og velg" DataGridColumn "fra listen som dukker opp. La alt annet til standardverdiene, og klikk "Finish". En ny fil skal ha blitt opprettet og befolket med følgende kode:
    pakke klasser {import mx.controls.dataGridClasses.DataGridColumn; public class NestedDataGridColumn strekker DataGridColumn {offentlig funksjon NestedDataGridColumn (Kolonne: String = null) {super (Kolonne); }}}
    Trinn 10: forkynner 'nestedDataField' Eiendom

    I NestedDataGridColumn klassen, legge til en offentlig bind variabel kalt 'nestedDataField'. Vi vil bruke dette i stedet for standard 'datafeltet' eiendom å passere navnefeltet. Dette er viktig, fordi hvis standard 'datafeltet' eiendom er brukt, en feilmelding som sier Feil: Finn kriterier må inneholde minst ett slags feltverdi. vil skje når vi prøver å sortere Datagrid etter å ha definert den egendefinerte sorteringsfunksjonen senere

    Trinn 11:. redefinerte 'itemToLabel' funtion

    Som du kan se, den nye klassen vi opprettet har allerede blitt befolket med en konstruktør. La konstruktøren som det er og under som legger følgende funksjon:
    styre offentlig funksjon itemToLabel (data: Object): String {var felt: Array; Var label: String; Var dataFieldSplit: String = nestedDataField; Var currentData: Object = data; //sjekke om nestedDataField verdien inneholder en '.' (dvs. er tilgang til en nestet verdi) if (nestedDataField.indexOf () = -1 ".") {//få alle feltene som må nås felt = dataFieldSplit.split ("."); for hver (var f: String i felt) //sløyfe gjennom feltene én etter én, og få den endelige verdien, går ett felt dypt hver iterasjon currentData = currentData [f]; if (currentData er String) //returnerer den endelige verdien retur String (currentData); } //Hvis det ikke er hekkende involvert else {if (dataFieldSplit = ""!) CurrentData = currentData [dataFieldSplit]; } //Hvis vår metode ikke har fungert som forventet, ty til å kalle standardfunksjon prøve {label = currentData.toString (); } Catch (e: Feil) {label = super.itemToLabel (data); } //Returnere resultatet returetiketten; }

    redefinerte 'itemToLabel "-funksjonen er nøkkelen til å kunne få tilgang nestet data i Datagrid. Den itemToLabel funksjonen styrer hva som skal vises i Datagrid rader. Så vi bruker det her for å spørre Flex vise de nestede data på den måten at vi har spesifisert.

    Som du kan se, starter funksjonsdefinisjonen med "overstyring" keyword, noe som betyr at standardforhåndsdefinerte funksjon med samme navn blir overstyrt i favør av den funksjonen du har definert. Hvert utsagn er forklart i kommentarfeltet. I korte trekk, hva funksjonen gjør er å sjekke om nestet datafeltene er i bruk (hvis a '.' Er til stede). Hvis det er, får hver datafeltnavn, og iterere gjennom dataprovider, går dypere hvert trinn ved å gå til barnet feltet.

    'itemToLabel' funksjonen kalles fra Flex med et argument som inneholder ArrayCollection som var angitt som dataprovider til Datagrid. Alle attributter av NestedDataGridColumn (når den brukes i MXML fil) er direkte tilgjengelige, og noen offentlige eiendommer som er definert i denne klassen kan tilordnes en verdi i MXML. I vår NestedDataGrid.mxml fil, vi erstatte 'mx: DataGridColumn' komponenter med "klasser: NestedDataGridColumn 'komponent, og tilordne spesifikke elementer som vi ønsker å vise i kolonnene til" nestedDataField' attributt (som ble erklært i ' NestedDataGridColumn.as 'fil). Den DataGridColumn nå skal se slik ut:
    < mx: Datagrid x = "10" y = "10" width = "{meetingsPanel.width-40}" height = "45%" dataprovider = "{dataForGrid}" > < mx: kolonner > < klasser: NestedDataGridColumn headerText = "Priority" nestedDataField = "priority" width = "60" /> < klasser: NestedDataGridColumn headerText = "Presenter Name" nestedDataField = "presenter.name" sorterbar = "false" /> < klasser: NestedDataGridColumn headerText = "Presenter Phone" nestedDataField = "presenter.phone" width = "90" sorterbar = "false" /> < klasser: NestedDataGridColumn headerText = "Dato" nestedDataField = "date" width = "110" /> < klasser: NestedDataGridColumn headerText = "Time" nestedDataField = "tid" width = "70" /> < klasser: NestedDataGridColumn headerText = "Place" nestedDataField = "sted" width = "70" /> < /mx: kolonner > < /mx: Datagrid >

    Merk at jeg direkte spesifisere 'nestedDataField' eiendom som "presenter.name" og "presenter.phone" her. Også har jeg lagt bredder til kolonnene og angi bredden av "mx: Panel 'komponent til 600px for bedre skjerm. Jeg har lagt den "sorterbar 'eiendom å være falsk til de to nye kolonner. Hvis du fjerner denne (eller sette den til true) og kjør programmet kolonnen vil ikke sortere. Vi vil løse dette i neste trinn ved å definere vår egen sorteringsfunksjon. For nå søknaden skal se slik ut:

    Trinn 12: Skrive Custom Sorter Function

    Det eneste som gjenstår nå er å definere tilpassede sorteringsfunksjon, slik at sortering vil også være aktivert i alle feltene (si, du ønsker å sortere de presenter navnene alfabetisk). Legg funksjonen kalles "mySortCompareFunction 'under' itemToLabel 'funksjon som gitt:
    privat funksjon mySortCompareFunction (obj1: Object, obj2: Object): int {var felt: Array; Var dataFieldSplit: String = nestedDataField; Var currentData1: Object = obj1; Var currentData2: Object = obj2; if (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]; }} If (currentData1 er int & & currentData2 er int) {var int1: int = int (currentData1); Var INT2: int = int (currentData2); Var resultat: int = (int1 > INT2) - 1: 1; returnere resultat; } If (currentData1 er String & & currentData2 er String) {currentData1 = String (currentData1); currentData2 = String (currentData2); avkastning (currentData1 > currentData2) - 1: 1;? } If (currentData1 er Date & & currentData2 er Date) {var date1: Date = currentData1 som dato; Var date2: Date = currentData2 som dato; Var date1Timestamp: Number = currentData1.getTime (); Var date2Timestamp: Number = currentData2.getTime (); avkastning (date1Timestamp > date2Timestamp) - 1: 1; } Return 0; }

    Denne funksjonen vil bli oppringt av Flex med to objekter, og det er forventet å returnere enten -1,0 eller en avhengig av om det første objektet er større enn, lik eller mindre enn henholdsvis det andre objektet. Flex tar seg av selve sorteringen.

    Denne funksjonen bruker samme logikk som "itemToLabel" -funksjonen for å få riktig nestet verdi. Så avhengig av type av verdien (enten det er int, String, eller dato) den sammenligner det på riktig måte, og returnerer -1 hvis 'currentData1 "er større enn" currentData2', 0 dersom de er like, og en hvis 'currentData2 'er større enn "currentData1'

    Trinn 13:. Kople til Custom Sorter Function

    Hvis du lagt merke til," er customSortCompareFunction 'ikke en forhåndsdefinert funksjon i klassen DataGridColumn som vi overstyre. Denne funksjonen må tilordnes som sorteringsfunksjon på en annen måte. Vi må tilordne forhåndsdefinerte variable 'sortCompareFunction' navnet på sorteringsfunksjon, som er "customSortCompareFunction" i vårt tilfelle. Dette bør gjøres inne i konstruktøren. Konstruktøren ser nå slik ut:
    offentlig funksjon NestedDataGridColumn (Kolonne: String = null) {//skikken sorteringsfunksjonen blir tildelt den forhåndsdefinerte variable sortCompareFunction = mySortCompareFunction; super (Kolonne); }

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

    Konklusjon

    I dag du lærte å omgå en begrensning av FlexDataGrid klassen for å få vilkårlig nestet data, og vise det i et Datagrid. Du har også lært hvordan man skal definere din egen sorteringsfunksjon, slik at rutenettet er fortsatt sorterbar. Du kan nå bruke denne NestedDataGridColumn i alle dine applikasjoner uten overhead

    Du kan videre utvide 'itemToLabel "-funksjonen til å omfatte andre vilkårlig format til innsyn -. Si, tilgang arrays inni ordnede objekter, eller tilgang til xml attributter . Du kan også ytterligere forlenge slags funksjon for å sortere andre typer data. Du kan også være i stand til å legge til andre funksjoner som fargelegger radene basert på møtet prioritet og viser flere detaljer om foreleser ved å klikke på rad.

    Takk for at du leser :) Anmeldelser



    Previous: