In tutti gli esempi precedenti ci siamo preoccupati solo di memorizzare i dati presi dall'XML in degli array, senza visualizzarli. Ovviamente la visualizzazione dei dati è una parte molto importante della nostra applicazione e porta alla luce non pochi problemi legati all'utilizzo di Flash per lo sviluppo di certe applicazioni.
Uno dei problemi che ho dovuto risolvere su Flash è la gestione dell'infinito. Sembrerebbe un concetto molto filosofico e in effetti lo è! :)
Mentre con l'HTML se noi dobbiamo creare una pagina dinamica utilizziamo uno script che crea l'output mettendo i dati uno dopo l'altro, perché tanto la pagina HTML indipendentemente dalla sua lunghezza potrà essere vista con lo scrolling della barra laterale, con Flash il discorso è ben più complesso in quanto abbiamo a disposizione un'area limitata le cui dimensioni sono fissate a priori e corrispondono alle dimensioni del filmato Flash.
Adesso con Flash MX sono stati introdotti dei componenti aggiuntivi che permettono di creare delle tabelle con lo scroll etc etc ma ovviamente il mio lavoro di ricerca e sviluppo era legato all'ultima versione disponibile di Flash in quel momento, ovvero la versione 5.
Tuttavia ci tengo a precisare che facendo delle prove con Flash MX utilizzando i componenti già pronti e realizzando la stessa applicazione con Flash 5 sostituendo i componenti già pronti con codice Action Script il risultato è che il filmato di Flash MX pesa 3 volte di più e ha una grafica molto più povera e standard. Per questo consiglio sempre di crearsi da se le proprie interfacce grafiche senza ricorrere ai componenti già pronti per ottenere deifilmati molto più leggeri e molto più belli e personalizzati.
Certamente se dobbiamo visualizzare del testo preso da un XML in un campo di testo dinamico con lo scroll il problema è alquanto semplice.
Per gestire l'infinito invece possiamo utilizzare un metodo dove i movie clip che contengono i dati dell'XML vengono annidati all'interno di un unico movie clip il cui scroll è gestito da due pulsanti e/o una barra di scroll. In questo modo abbiamo un'area ben definita all'interno della quale possiamo gestire l'infinito, visualizzando un numero elevato di movie clip che contengono i nostri dati.
Per la visualizzazione dei dati possiamo adottare due metodi e gestire il problema sia sfruttando il codice Action Script di Flash
lato client che lo script lato server che ci fornisce il documento XML.
Nel primo metodo possiamo decidere a priori quanti risultati vogliamo far visualizzare sul nostro filmato Flash e gestire il tutto con la "paginazione" (cioè con un massimo di elementi/risultati per pagina). In questo caso lo script lato server ci fornisce solo n risultati dove n è minore o uguale al numero massimo che abbiamo stabilito. Gli altri risultati sono visibili nelle altre pagine. In questo caso quindi dobbiamo visualizzare dei pulsanti associati alle diverse pagine e dobbiamo poter gestire l'infinito per quanto riguarda il numero delle pagine se questo tende a diventare un numero grande. Questo metodo è molto interessante in quanto il filmato non carica tutti i dati presenti all'interno del Data Base (il che potrebbe creare un
documento XML molto grande e pesante da essere caricato) ma solamente n alla volta.
Nel secondo metodo invece visualizziamo i nostri dati direttamente in un'area del filmato dove viene gestito l'infinito indipendentemente dal fatto che gli elementi che contengono i dati dell'XML siano pochi o molti. Questo metodo potrebbe essere un po' rischioso in quanto il documento XML potrebbe diventare molto pesante per essere caricato.
E' quindi importante fare una valutazione attenta dell'applicazione che si sta realizzando per scegliere la soluzione ottimale per la visualizzazione dei dati.
Mostriamo degli esempi pratici di entrambi i metodi.
Primo metodo: "paginazione" dei risultati con Flash.
Illustriamo come utilizzare il metodo della "paginazione" con gestione dell'infinito per i movie clip delle pagine.
Nell'esempio utilizzeremo lo script ASP che crea l'XML (con qualche modifica per la "paginazione"), lo stesso codice Action Script dell'esempio precedente aggiungendo però alcune funzioni e lo stesso Data base.
Script ASP (read_db.asp)
<%
Const adOpenKeyset = 1
Const adLockReadOnly = 1
' Stringa di Connessione al Data Base con la password che viene specificata
' Modificate se necessario il percorso del Data Base sostituendo a "/guidaflash" il nome della vostra cartella che conterrà il DB
StrConnessione = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" & server.MapPath("/guidaflash") & "db.mdb"
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open StrConnessione
' Selezioni dalla tabella voli i dati ordinati in modo crescente in base alla ora di partenza
SQL = "SELECT * FROM voli order by hpartenza asc"
' Creo il RECORD SET che contiene tutti i dati selezionati dal Data base
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open SQL, Conn, adOpenKeyset,adLockReadOnly
' Eseguo la paginazione del record set suddividendo i risultati trovati in pagine e selezionando solo la pagina richiesta
PageNumber = 1
if not isnull(request("PageNumber")) and request("PageNumber") <> "" then
PageNumber = cint(request("PageNumber"))
RsIn = (Pagenumber - 1) * 8
rs.move(RsIn)
end if
numrec=8
' Eseguo un ciclo su tutti i dati del Recod set e creo il documento XML in output con i vari TAG
Do while not rs.eof and numrec > 0
Response.Write "<volo id=""" & rs("idvolo") & """/><partenza h=""" & rs("hpartenza") &""">" & rs("partenza") & "</partenza><arrivo h=""" & rs("harrivo") &""">"& rs("arrivo") &"</arrivo>"
rs.movenext
numrec = numrec -1
Loop
'aggiungo al documento XML un nodo che contiene il numero totale di record
response.write "<totrec>"& rs.recordcount &"</totrec>"
rs.close
set rs=nothing
Conn.Close
set Conn=nothing
%>
Le modifiche che abbiamo apportato riguardano la "paginazione" dei risultati. Lo script restituisce massimo 8 risultati alla volta in base alla pagina. Se ad esempio abbiamo in tutto 10 risultati lo script restituisce due pagine, la prima con 8 risultati e la seconda con soli 2 risultati. Un'altra modifica è l'aggiunta nel documento XML di un elemento <totrec> che contiene il numero di record totali selezionati dal Data Base. Questo numero è importante perché poi grazie ad esso siamo in grado di creare i movie clip relativi alle pagine su Flash.
Per vedere il risultato dello script, ovvero il documento XML andate su questo URL http://www.enricolai.com/guidaflash/read_db.asp e guardate il "view source HTML" dal browser per vedere l'intero documento XML con i suoi TAG.
Vediamo ora come procedere col filmato Flash (es9.fla)
Prima di tutto vediamo il codice Action Script:
fscommand ("allowscale", "false");
filexml = "http://www.enricolai.com/guidaflash/read_db.asp?PageNumber=1";
paginainiziale="01";
ApriXML();
function ApriXML () {
_root.loading = "Connecting to Data Base for XML data...";
mioxml = new XML();
myarray = new Array();
mioxml.load(filexml + "&rnd=" + random(999999));
mioxml.onLoad = ElaboraXML;
function ElaboraXML (success) {
if (mioxml.loaded) {
myarray = mioxml.childNodes;
Dati();
MenuPag();
CreaTabelle();
delete myarray;
delete mioxml;
}
};
};
// Funzione che prende i dati XML e li mette in degli Array
function Dati () {
// Array che contengono i Dati -----------------------
idvolo = new Array();
hpartenza = new Array();
harrivo = new Array();
partenza = new Array();
arrivo = new Array();
// ---------------------------------------------------
for (k=0; k<=myarray.length; k++) {
if (myarray[k].nodeName == "volo") {
idvolo.push(myarray[k].attributes.id);
} else if (myarray[k].nodeName == "partenza") {
hpartenza.push(myarray[k].attributes.h);
partenza.push(myarray[k].childNodes.toString());
} else if (myarray[k].nodeName == "arrivo") {
harrivo.push(myarray[k].attributes.h);
arrivo.push(myarray[k].childNodes.toString());
} else if (myarray[k].nodeName == "totrec") {
_root.totrec=myarray[k].childNodes.toString();
}
};
};
// Funzione che crea il menù delle pagine con gestione dell'infinito
function MenuPag(){
numero = Math.floor((totrec-0.5)/8+1);
nmaxpag = numero;
for (i=0; i<numero; i++){
barranav.attachMovie("page", "pagine"+i,i+100);
barranav["pagine"+i]._x =10+i*25;
barranav["pagine"+i]._y =10;
k=i+1;
if (k<=9){app="0"+k}else{app=k};
barranav["pagine"+i].pagina=app;
barranav["pagine"+i].PageNumber = k;
if (k<=9){nmaxpag ="0"+ k;}
else {nmaxpag=k};
_root.loading = paginainiziale+"/"+nmaxpag+" - TOT MESSAGGI "+ totrec ;
};
};
// Funzione che Crea i clip
// e li posiziona sullo stage del filmato
function CreaTabelle () {
for(i=0; i<idvolo.length; i++) {
attachMovie("clipmsg", "clipmsg"+i, i);
// Attribuisco la coordinata X e Y&
_root["clipmsg"+i]._x = 25
_root["clipmsg"+i]._y = 25+i*41;
// Passo al clip le variabili che ho preso dall'XML e messo negli Array
_root["clipmsg"+i].idvolo = idvolo[i];
_root["clipmsg"+i].hpartenza = hpartenza[i];
_root["clipmsg"+i].harrivo = harrivo[i];
_root["clipmsg"+i].partenza = partenza[i];
_root["clipmsg"+i].arrivo = arrivo[i];
};
};
// Funzione che rimuove tutti i Clip dalla scena prima di posizionare i clip della nuova pagina
function Rimuovi(){
for (a=0; a<idvolo.length; a++){
_root["clipmsg"+a].removeMovieClip();
};
};
Osserviamo il codice.
Sostanzialmente abbiamo aggiunto alcune funzioni che andremo a vedere nel dettaglio. Il funzionamento del codice non dovrebbe essere difficile da capire. Nell'esempio 8 ci siamo fermati al punto in cui i dati venivano messi negli array.
Dopo aver messo i dati negli array abbiamo costruito 3 funzioni per la visualizzazione:
- MenuPag()
- CreaTabelle ()
- Rimuovi()
La funzione MenuPag() sfrutta il valore di totrec (valore preso dall'XML che indica il numero totale di record presenti nel Data base -> vedere lo script ASP) per calcolare il numero di pagine da visualizzare. Quindi crea i movie clip relativi alle pagine attraverso il metodo attachMovie inserendo i clip "page" (aprite la libreria, selezionate col tasto destro il clip "pag" e andate su "Concatenamento..." e vedrete che il nome del clip nelle proprietà di concatenamento è "page" ( on-line demo: http://www.enricolai.com/guidaflash/demo_1/page.htm )) all'interno del clip vuoto "barranav". Il movie Clip vuoto "barranav" ( on-line demo: http://www.enricolai.com/guidaflash/demo_1/barranav.htm ) si trova in un livello mascherato e ha il seguente codice Action Script associato:
onClipEvent (load) {<br>
xiniz = this._x<br>
}<br>
onClipEvent (enterFrame) {
x = _x;
x_fin = ((-_parent.counter)*25)+xiniz;
dx = x_fin-x;
dx /= 2.5;
_x += dx;
}
Questo codice Action Script ci permette di gestire lo scroll di "barranav" e quindi dei movieClip "pagine" che si trovano al suo interno, muovendosi in base al parametro "counter" che viene modificato dai tasti sul livello button.
Il codice associato ai pulsanti è il seguente:
//Pulsante destro:
on (release) {
if (_root.counter < (_root.numero-1)){
_root.counter++
}
}
//Pulsante sinistro:
on (release) {
if (_root.counter >0) {
_root.counter--;
}
}
Vediamo ora come è costituito il clip "pag" ( on-line demo: http://www.enricolai.com/guidaflash/demo_1/pag.htm ) della libreria. Selezioniamolo col tasto destro del mouse e andiamo su "Modifica". Il clip è costituito da due livelli: il primo contiene un campo di testo dinamico, mentre il secondo contiene il pulsante che ci permette di cambiare pagina grazie al seguente codice Action Script associato ad esso:
on (release) {
_root.filexml = "http://www.enricolai.com/guidaflash/read_db.asp?PageNumber="+this.PageNumber;
_root.Rimuovi();
_root.ApriXML();
if (PageNumber<=9) {
app = "0"+PageNumber;
} else {
app = PageNumber;
};
_root.paginainiziale = this.app;
}
Come potete osservare sostanzialmente il codice Action Script ci permette di richiamare lo script ASP passandogli il parametro "PageNumber" che indica la pagina di dati da mettere nel documento XML, rimuovere i movie Clip dei dati dalla scena e caricare nuovamente il documento XML.<
La funzione CreaTabelle () invece crea i movie clip per visualizzare i dati prelevati dal documento XML. Anche in questo caso sfruttiamo il metodo dell'attachMovie e prendiamo dalla libreria i clip che nelle proprietà di concatenamento si chiamano "clipmsg" ( on-line demo: http://www.enricolai.com/guidaflash/demo_1/clipmsg.htm ) e li posizioniamo all'interno del nostro filmato.
Infine la funzione Rimuovi() viene utilizzata per rimuovere i movie clip "clipmsg" dal filmato quando avviene un cambio di pagina.
Vediamo infine il funzionamento della nostra applicazione a questo URL: http://www.enricolai.com/guidaflash/es9.html