AS3 - LoadVars va in pensione...

... e cede il passo alla classe URLLoader

Inserito il 10-08-2007

Chi lavora abitualmente con Actionscript per lo scambio di dati con fonti esterne, come database o file di testo, non potrà non sentire in AS3 la mancanza di questa classe ormai divenuta praticamente indispensabile a questo scopo (altra possibilità era l'uso di loadVariables/loadVariablesNum, dichiarate obsolete da Flash mx a favore appunto della classe LoadVars, molto più stabile e di facile utilizzo), ma si potrà comunque abituare abbastanza facilmente a questa nuova classe, da utilizzarsi in accoppiata con altre due per completare il tutto, URLRequest ed URLVariables, la prima preposta alle richieste di url, con l'aggiunta di proprietà necessarie al momento in cui sia flash che deve inviare dei dati all'esterno, la seconda invece utilizzata come "stiva" delle informazioni ottenute dall'esterno o da inviare da flash.

Tutto il discorso risulterà sicuramente più semplice da affrontare nel momento in cui vedremo gli esempi pratici in merito. Tenterò nell'articolo di seguire la "linea" della classe LoadVars affrontandone i metodi per fare un rapido confronto con il nuovo approccio.

Innanzi tutto vediamo i metodi principali, fino ad ora utilizzati con la classe LoadVars:

LoadVars.load(url:String) -> URLLoader.load(request:URLRequest)

Il primo metodo che prendiamo in considerazione è il più semplice, quello che richiama delle variabili da un url specifico, ad esempio un file di testo. Chi utilizzava LoadVars sa bene che l'output del file esterno, doveva essere presentato a Flash con una certa formattazione, per fare in modo che ActionScript riconoscesse i nomi delle variabili e il loro contenuto, il modo era praticamente uguale a quello di una querystring, in cui le variabili vengono separate dalla lettera & e il contenuto viene determinato dal segno =, ad esempio:

variabile1=contenuto della variabile1&variabile2=contenuto della variabile2&variabile3=contenuto della variabile3

Per fortuna tale metodo di ricezione rimane invariato in AS3, anche se cambia un po' il modo di "presentare" il codice, ne facciamo subito un esempio e lo commentiamo:

// inizializzo una variabile che contiene il nome del file esterno da caricare
// contenuto di test.txt -> variabile1=contenuto della variabile1&variabile2=contenuto della variabile2&variabile3=contenuto della variabile3
var external_file:String = "test.txt";
// inizializzo una richiesta sull'url che mi interessa
var request:URLRequest = new URLRequest(external_file);
// inizializzo una nuova istanza dell'urlloader
var ex_loadvars:URLLoader = new URLLoader();
// aggancio all'oggetto appena creato i due eventi principali che mi interessa monitorare
// il primo mi notifica la ricezione delle variabili e ne stabilisce il modo di utilizzo
// il secondo mi notifica gli errori, in caso di mancanza del file o altri errori di input/output
ex_loadvars.addEventListener(Event.COMPLETE, completeHandler);
ex_loadvars.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
// la funzione completeHandler viene richiamata nel momento in cui le variabili possono essere utilizzate
function completeHandler(event:Event) {
	// attraverso una nuova istanza della classe URLVariables recupero le variabili esterne
	var vars:URLVariables = new URLVariables(event.target.data);
	// traccio le variabili di cui ho la consapevolezza del nome
	trace(vars.variabile1); // output: "contenuto della variabile1"
	trace(vars.variabile2); // output: "contenuto della variabile2"
	trace(vars.variabile3); // output: "contenuto della variabile3"
}
// la funzione errorHandler viene richiamata se ci sono dei problemi di comunicazione con il file esterno
function errorHandler(event:IOErrorEvent) {
	trace("Problemi!");
}
// dopo aver predisposto la gestione delle variabili ricevute, avvio la ricezione tramite il metodo load
// passandogli come parametro la richiesta url inizializzata in precedenza
ex_loadvars.load(request);

Risulta forse evidente che le righe di comando utilizzate rispetto a quelle del LoadVars, sono di più, ma si può anche considerare una maggiore solidità nel codice, grazie all'utilizzo della gestione ad eventi, di cui abbiamo già visto in un precedente articolo

LoadVars.send(url:String, target:String, [method:String]) -> flash.net.sendToURL(request:URLRequest)

Al contrario di load e sendAndLoad, il semplice send non viene richiamato dalla classe URLLoader, questo perchè con il send non ci deve essere interazione tra lo script AS e la pagina che riceve i dati, in pratica la pagina che riceve viene aperta ma non restituisce nulla a flash e continua la "sua strada" per conto suo, gestendo le variabili ricevute da flash nella maniera che si preferisce.
Così molto semplicemente il codice che compone questa chiamata si limita al seguente esempio:

// inizializzo una variabile che contiene il nome del file a cui inviare i dati
var url:String = "test.php";
// inzializzo un oggetto URLVariables preposto a contenere le variabili da inviare e lo riempio con due variabili
var variables:URLVariables = new URLVariables();
variables.prova1 = "prima variabile";
variables.prova2 = "seconda variabile";
// a questo punto creo un nuovo oggetto URLRequest che "riempirò" con le variabili da inviare allo script esterno
// e accedendo alla sua proprietà "data" gli assegno l'oggetto URLVariables creato e riempito in precedenza
var request:URLRequest = new URLRequest(url);
request.data = variables;
// l'ultimo passo è il richiamo della funzione contenuta nel package "flash.net", che invia le variabili all'url richiesto
// senza aspettarsi una risposta in cambio
sendToURL(request);

Possiamo notare dall'esempio che la gestione delle variabili in "uscita" viene fatta dalle due classi URLVariables e URLRequest, nota importante da prendere in considerazione nella descrizione di utilizzo dell'ultimo metodo, che è più che altro una "unione" dei due appena visti load e send.

LoadVars.sendAndLoad(url:String, target:Object, [method:String]) -> ?

Il punto interrogativo nel titolo di questo paragrafo non è messo a caso, infatti la questione è che per il sendAndLoad non esiste un metodo sostitutivo, per sostituire tale metodo bisogna utilizzare una combinazione di invio delle variabili e di ricezione di una risposta. La cosa è facilmente fattibile unendo effettivamente i due codici visti fino ad ora, analizzando il modo di agire in due passi successivi:

Probabilmente la gestione, letta in questo modo, appare un po' troppo semplificata e i passi da seguire a livello di codice non sono chiari, utilizziamo perciò il solito esempio di codice commentato per capire meglio tutto il discorso.

// inizializzo una variabile che contiene il nome del file a cui inviare i dati
var url:String = "test.php";
// inizializzo un'oggetto URLVariables che mi contenga le variabile da spedire allo script
var send_vars:URLVariables = new URLVariables();
// riempio l'oggetto con le variabili che preferisco e che serviranno nello script esterno a determinare
// l'output da reinviare a flash
send_vars.test = "test";
// Ancora una volta, come per i precedenti esempi, creo un nuovo oggetto URLRequest che "riempirò" con le variabili 
// da inviare allo script esterno e accedendo alla sua proprietà "data" gli assegno l'oggetto URLVariables creato e riempito in precedenza
var request:URLRequest = new URLRequest(url);
request.data = send_vars;
// accedendo alla proprietà "URLRequest.method" decido con quale metodo inviare i dati allo script esterno
request.method = "POST";
// inizializzo una istanza della classe URLLoader
var loader:URLLoader = new URLLoader();
// e gli assegno gli eventi "complete" e "ioError"
loader.addEventListener(Event.COMPLETE, completeHandler);
loader.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
// ancora una volta inizializzo le funzioni da richiamare nelle fasi dichiarate con il metodo addEventListener
function completeHandler (event:Event) {
	// nell'evento "complete" creo un nuovo oggetto che mi contiene le variabili restituite dallo script esterno
	// che avranno un output diverso a seconda di come lo script ha processato i dati ricevuti in precedenza dallo stesso script AS
	var return_vars:URLVariables = new URLVariables(event.target.data);
	// traccio la variabile che mi interessa verificare
	trace(return_vars.ritorno);
}
// la funzione errorHandler viene richiamata se ci sono dei problemi di comunicazione con il file esterno
function errorHandler(event:IOErrorEvent) {
	trace("Problemi!");
}
// affido al metodo "load" l'URLRequest che contiene le informazioni da utilizzare nello script esterno e che restituiranno un output 
//diverso, a seconda del loro contenuto e sancisco in questo modo la chiusura del "cerchio" con l'invio e la ricezione di dati dallo script esterno
l.load(request);

Così, a seconda di come lo script esterno interpreterù i dati, avremo un output da utilizzare in flash, a nostro piacimento, come abbiamo sempre fatto anche con il sendAndLoad della classe LoadVars.

Direi che il quadro generale è completo, spero che l'articolo aiuti a facilitare l'approccio sulla nuova gestione dei dati esterni, precedentemente affidata alla classe LoadVars.