Introduzione
Il mondo dello sviluppo in Flash è pieno di sorprese e di risorse. La sua crescita, che attualmente procede più velocemente rispetto al passato, ha portato un interesse da parte degli sviluppatori e, di conseguenza, un aumento di risorse che possono risultare utili per qualsiasi developer. La risorsa che andiamo a prendere in considerazione oggi è un framework per lo sviluppo con Flex. Stiamo parlando del Mate Framework (si pronuncia Mah-Teh).
Un framework comodo da usare, assolutamente non intrusivo, che permette di sviluppare delle Rich Internet Application (RIA) facendo riferimento al paradigma MVC (Model View Controller) e ad un modello molto orientato all'uso di tag ed eventi, nella sua applicazione pratica.
Nello svolgimento di questo articolo, per prima cosa daremo uno sguardo alla terminologia e ai concetti principali che dobbiamo conoscere per poter sfruttarne al massimo le funzionalità. Poi inizieremo a vedere com'è strutturato il framework a livello generico, osservandone le peculiarità e come si è evoluto nel corso della sua storia. Da dove è nato e quali sono le eventuali alternative. Avendo una conoscenza basilare teorica potremo procedere al passo successivo, ovvero la realizzazione di un “Hello World" tipico in modo tale da prendere familiarità con la fase di creazione del progetto. Dopo il primo impatto pratico, per finire, daremo uno sguardo veloce ai vari tag previsti dal framework,. Arriveremo, quindi, alla fine di questo percorso con un bagaglio tutto sommato completo e sufficiente per poter fare qualcosa da soli. Non perdiamo altro tempo ed iniziamo!
Event-Driven? MVC?
Avendo a che fare con il Mate Framework, occorre conoscere e tenere a mente alcuni termini e concetti dell'informatica e della programmazione. Eviteremo di perdere troppo tempo, soffermandoci solo nel cercare di capire i due concetti principali e senza dubbio più importanti: la programmazione ad eventi (in inglese “Event-Driven Programming") e il pattern MVC (sigla corrispondente a Model – View – Controller, in italiano spesso e volentieri tradotto come Modello – Vista – Controllore).
Iniziamo subito dalla programmazione basata sugli eventi. I più “anziani" sicuramente hanno presente la cosiddetta programmazione strutturata: la lista di istruzioni per eccellenza che viene presa ed eseguita, riga per riga, così come vengono viste sullo schermo durante la fase di modifica del codice. Un esempio su tutti? Il caro vecchio C. Da lì in poi la programmazione è cambiata, si è evoluta e col tempo sono nate nuove tecniche e nuovi metodi per avvicinarsi allo sviluppo. La programmazione basata sugli eventi vede, aldilà di qualsiasi astrazione, ogni programma diviso in due parti. Nella prima parte si controllano le condizioni che possono portare ad una determinata situazione (il click con il pulsante del mouse, un tasto sulla tastiera che viene premuto oppure un messaggio proveniente da un altro programma, o un thread dello stesso in esecuzione); nella seconda parte, invece, viene gestito l'insieme di procedure che rappresentano il “cosa fare al verificarsi di quella condizione". In inglese questa fase si chiama Event Handling, ovvero gestione degli eventi.
Fortunatamente, utilizzando i vari framework (tra cui anche il nostro Mate), non avremo mai bisogno di doverci scrivere da zero una struttura così suddivisa. Come vedremo, anche in questo caso non dovremo fare altro che “contemplare" le varie condizioni da gestire e scrivere di conseguenza il codice. Come si può ben immaginare, la creazione di questo tipo di tecnica ha avuto una diffusione enorme in tutte le applicazioni che prevedono interfacce grafiche: basti pensare alla stretta correlazione (nei suoi esempi più basilari ed intuitivi) di condizione come input da parte dell'utente e relativo evento da richiamare.
Passiamo ora ad un altro termine sicuramente molto in uso tra gli addetti ai lavori e che merita una dovuta spiegazione: il Pattern MVC.
Sostanzialmente, un pattern può essere definito come uno “stile" di programmazione, nello stendere il proprio codice in un determinato modo, con particolari accorgimenti. Non parliamo di precisi algoritmi, semmai di tecniche. Tuttavia, nel corso del tempo alcuni di questi approcci sono diventati oltremodo adatti alla risoluzione di determinati problemi e creazione di programmi specifici. Questi stili sono stati ribattezzati “Pattern": una soluzione riutilizzabile nel tempo ad un problema considerato comune.
L'MVC è uno di questi pattern. La concezione alla base che lo contraddistingue dagli altri è un'attenta suddivisione del programma in più sezioni logiche. Da una parte troviamo i dati, la logica del funzionamento del programma. Dall'altra ancora tutto ciò che riguarda la presentazione dei dati e l'input dell'utente. Si fa quindi un'ulteriore suddivisione che porta a comprendere il vero significato del nome: il Model equivale ai dati e alle procedure che operano su di essi; la View, come il nome suggerisce, racchiude tutto ciò che concerne l'output proposto all'utente; il Controller, infine, si occupa di gestire tutto ciò che concerne l'input da parte dell'utente.
In questo modo, in programmi complessi con più persone al lavoro, è possibile dividere sensibilmente e senza ripercussioni negative il carico di lavoro, in modo tale da non avere conflitti di nessun genere. Un caso degno di nota è senza dubbio la libreria Swing per Java: un insieme di sistemi MVC dove ogni componente grafico che viene messo a disposizione dell'utente non è altro che una triade logicamente composta da un Model, un View e un Controller.
Ora che abbiamo ben chiaro il tutto, possiamo procedere verso la pratica. Vediamo come scaricare e configurare per la prima applicazione il nostro framework.
Il Mate Framework
Affrontare il Mate Framework significa anche esplorarne le peculiarità, cercando di comprendere al meglio i concetti principali. Abbiamo già parlato del fatto che è un framework che vede le sue applicazioni guidate dagli eventi: questo vuol dire che dovremo innanzitutto ragionare tenendo a mente questa visione delle cose. Inoltre, avendo a che fare con uno sviluppo tag-based, dobbiamo considerare alcuni tag che sono considerati principali. Ovviamente parlo dei tag che andremo a mettere nei file dei componenti MXML che creeremo.
Il tag cardine, necessario ed essenziale, è EventMap
. Traducibile letteralmente con “Mappa degli Eventi", serve ad elencare le condizioni (e successivi effetti) di un determinato evento che prevederemo: a cosa porta il click su quel pulsante? E l'immissione di testo in quella casella? Sono tutte domande alle quali daremo una risposta precisa menzionando nella EventMap tutti i relativi comportamenti. In genere la EventMap viene realizzata proprio in un file MXML a parte, dentro il quale ci sono tutte le definizioni.
A questo punto scendiamo nella gerarchia, arrivando a parlare del tag EventHandlers
. Tramite l'attributo type
definiremo il tipo di evento da gestire, mentre all'interno del tag vero e proprio inseriremo le istruzioni da eseguire quando le condizioni necessarie si verificheranno. All'interno del tag EventHandlers
andranno, successivamente, altri tag da usare in varie situazioni. Vediamo velocemente quali sono questi tag:
MethodInvoker
EventAnnouncer
WebServiceInvoker
HTTPServiceInvoker
RemoteObjectInvoker
ObjectBuilder
DataCopier
StopHandlers
InlineInvoker
CallBack
DelegateInvoker
Sicuramente, uno dei più utilizzati è il primo: MethodInvoker
. Serve a creare un'istanza di un oggetto e richiamarne successivamente un metodo. Una funzionalità base, ben diversa da EventAnnouncer
, che invece si occupa di fare in modo, da un evento, di scatenare le condizioni necessarie a richiamarne un altro.
Abbiamo quindi gli strumenti per comunicare con i servizi web: parlo di WebServiceInvoker
, HTTPServiceInvoker
, RemoteObjectInvoker
e così via. Tuttavia, vedremo più tardi e nel dettaglio cosa ci serve: evitiamo di perdere troppo tempo adesso, confondendoci le idee. Ormai le nostre conoscenze, infatti, sono abbastanza consolidate dal punto di vista teorico. Non perdiamo altro tempo ed iniziamo a lavorare sul codice.
Download e installazione
Analizziamo ora quelli che sono i passi necessari per una corretta installazione del framework e per la successiva configurazione dell'ambiente di sviluppo. Il primo passo da fare è andare all'indirizzo http://mate.asfusion.com/page/downloads, ovvero sulla sezione 'Downloads' del sito ufficiale del progetto. Qui troveremo informazioni su tutte le possibili modalità di download: possiamo prelevare direttamente il file SWC (nel momento in cui scrivo è compatibile con Flex 3 e 4) oppure lavorare con strumenti di lavoro diversi, in base alle proprie esigenze. L'accesso all'SVN, il repository su GitHub, Maven e così via. Inoltre, sarà possibile scaricare anche il logo del progetto in vari formati e accedere al download della documentazione da consultare offline, nel caso non si abbia sempre a disposizione una connessione ad internet.
Possiamo procedere al download: in questo caso useremo il file SWC. Una volta terminato il breve download (si parla all'incirca di 330kb di componente) il passo successivo è configurare correttamente l'ambiente di sviluppo: in questo caso useremo Adobe Flash Builder 4. Avviamo l'IDE e, nel menu principale “File", optiamo per la creazione di un nuovo progetto Flex (New Flex Project).
Nella prima schermata che ci ritroveremo davanti dovremo decidere un nome per il nostro progetto. Chiamiamolo “MateTest". Lasciamo su “Web" il tipo di applicazione da creare e, infine, impostiamo su PHP il tipo di servizio web da utilizzare.
Dopo aver cliccato su 'Next' ci ritroveremo davanti una seconda schermata di impostazione, nella quale dovremo dare all'IDE maggiori informazioni per quanto riguarda il nostro ambiente di lavoro PHP. Per i test ho utilizzato l'ambiente XAMPP, che ha tutto ciò di cui c'è bisogno. Potete scaricarlo gratuitamente dal sito ufficiale. Tornando a noi, le informazioni delle quali abbiamo bisogno sono essenzialmente due: la cartella principale del server (nel mio caso C:/xampp/htdocs, che è quella di default) e l'indirizzo da utilizzare per richiamare le varie pagine (in questo caso http://localhost, dato che il server è in locale). Prima di poter confermare dovremo cliccare su “Validate Configuration". Se le impostazioni saranno valide, allora ci verrà notificato come in figura e potremo cliccare su “Finish". Il progetto è stato creato, ma il vero lavoro inizia solo ora.
La prima cosa da fare è associare al nostro progetto il Mate Framework: per fare questo, non dobbiamo fare altro che trascinare il file SWC da noi scaricato nella cartella “libs" appena creata da Flash Builder. Il tutto senza troppe operazioni, ma semplicemente con un classico drag and drop direttamente nell'IDE.
Prima di continuare, occorre fare una piccola panoramica di quello che faremo. Stiamo creando questo primo progetto, che avrà come scopo principale il prelevare dei risultati da un WebService e mostrarli. Grazie al Mate Framework e all'applicazione del pattern MVC, divideremo la logica dalla presentazione in modo tale da creare un ambiente di lavoro decisamente più efficiente del normale. Il prossimo passo, quindi, sarà creare un altro progetto in PHP che consisterà nel WebService: torneremo solo dopo al nostro progetto Flex per effettuare il collegamento e realizzare l'applicazione.
Creazione del WebService in PHP
Per la nostra prima prova utilizzeremo un servizio web piuttosto semplice: ci limiteremo a creare una classe con al suo interno un metodo che restituisca una stringa in output (qualcosa come “Hello World, Hi NOME” dove al posto di “NOME” avremo una stringa data in input, tramite una casella di testo nell'interfaccia dell'applicativo in Flex. Per ora però scolleghiamoci da eventuali discorsi di interfacce, input ed output: dobbiamo infatti concentrarci solo ed esclusivamente sul servizio web e sulla sua logica.
Innanzitutto dobbiamo vedere nel dettaglio cosa ci serve per affrontare questo compito. Per quanto riguarda la creazione del Progetto PHP, utilizzeremo Eclipse per PHP.
Inoltre, dato che stiamo parlando del realizzare un servizio PHP con lo scopo di comunicare con un “client” che noi creeremo utilizzando Flex, servirà un “ponte” che ci permetta di far comunicare senza problemi queste due tecnologie. Nel passato le soluzioni adottate sono state decisamente tante, e di vario genere: la serializzazione è stata effettuata anche grazie a semplici file di testo con successivo caricamento nel file SWF tramite l'istruzione loadVars
. La community, da allora, ha fortunatamente fatto svariati passi in avanti ed oggi possiamo avere dalla nostra parte un servizio ottimo per la comunicazione, AMFPHP. Il potente strumento in questione utilizza una procedura ben precisa per assolvere al suo compito: la cosiddetta RPC (Remote Procedure Call).
Come d'altronde il nome indica, è una chiamata ad una procedura remota, presente su un altro oggetto al di fuori dell'ambito dal quale effettuiamo, appunto, la chiamata. Sarà proprio AMFPHP ad effettuare tutte le operazioni di astrazione necessarie ad evitare il misunderstanding tra i vari tipi di dati da un linguaggio all'altro. Per approfondimenti rimando all'articolo Introduzione ad AMFPHP: far comunicare PHP e Flash.
Possiamo passare alla pratica adesso: creiamo un nuovo progetto PHP dalla struttura piuttosto semplice: ecco di seguito la struttura dei file che ho adottato personalmente.
Il progetto è stato salvato nella cartella “services” di AMFPHP. Presenta un solo file: “WebService.php” che porta al suo interno le poche e semplici istruzioni che ci servono. Tutto quello che il servizio web fa è prendere in input un nome e restituirlo. Nel caso non sia stato specificato niente, allora viene restituita la stringa “What's your name?” (Qual'è il tuo nome?). Qui di seguito il listato del file WebServiceTest.php:
<?php class WebServiceTest { function helloWorld($nome) { $name = ucfirst(strtolower($nome)); if($name != "") { return "Hello World, Hi $name!"; } else { return "What's your name?"; } } } ?>
Dopo aver salvato le modifiche al nostro progetto, possiamo dichiararlo completato. Un'altra parte è andata ed ora possiamo chiudere Eclipse dato che ha assolto al suo compito perfettamente. Il prossimo passo sarà quello di tornare in Flash Builer 4, collegare il progetto esistente al servizio web appena creato e quindi lavorarli per ottenere il nostro tanto agognato “Hello World”.
Il progetto in Flash Builder
Una volta impostato l'ambiente di sviluppo e realizzato correttamente il servizio web, non rimane altro che mettersi all'opera sul programma “client" da utilizzare. A questo punto, infatti, possiamo ritornare a Flash Builder. Se abbiamo chiuso il programma, riapriamolo e carichiamo nuovamente il progetto che abbiamo creato poco fa. È adesso che mettiamo in pratica le conoscenze acquisite in precedenza.
Innanzitutto, avremo bisogno di un file di configurazione per l'utilizzo di AMFPHP. Lo scrivo qui perché riguarda il progetto che stiamo facendo in Flash Builder. Nel pannello di esplorazione del progetto, cliccate con il pulsante destro sulla cartella “src", aprendo il menu contestuale e selezionando successivamente “New > File". Chiamatelo “services-config.xml" e copiate il contenuto dello snippet che trovate su questa pagina. A questo punto salvate il file, non ci sono altre modifiche da fare.
Lo step successivo è creare le cartelle necessarie a contenere il codice e i vari file corrispondenti. In questo caso è stata riprodotta la stessa struttura standard per evitare malfunzionamenti. Come prima, clicchiamo con il pulsante destro del mouse sulla cartella “src": stavolta però clicchiamo su “New > Folder". Diamo il nome alla nuova cartella “com/asfusion/helloworld/mate/events". In questo modo creeremo più velocemente la struttura senza dover ripetere la cosa per ogni livello.
Nella cartella “mate", adesso, oltre alla cartella “events" creiamone altre due: “maps" e “views". La funzione di questa suddivisione è ovvia: per rispettare il pattern MVC occorre dare la giusta struttura fin dall'inizio in modo tale da sapere “dove" mettere i vari componenti mano a mano che si realizzano. Ciò non toglie che le cose siano strettamente collegate: dalle views (che gestiscono l'interazione con l'utente) vengono realizzate le condizioni per l'avvenire di un determinato evento. A quel punto si fa riferimento alle Maps per capire cosa fare. Ad ogni modo, adesso il nostro Package Explorer apparirà diversamente.
Partiamo quindi dalla cartella “events". Al suo interno, creiamo un nuovo file di tipo “Actionscript Class". Il nome che sceglieremo sarà “HelloWorldEvent" e sarà ereditata dalla classe Flash.Event
. Non c'è altro da decidere: basterà dare questi dettagli e cliccare su “Finish" per creare la struttura automaticamente. Adesso, provvediamo a cambiare alcune piccole cose. Innanzitutto impostiamo su true
la proprietà bubbles
passata come argomento nel metodo costruttore della classe.
Provvediamo a creare il resto della classe. Innanzitutto una costante statica di tipo String, che chiameremo GET
. Dopodiché una variabile, sempre di tipo string, chiamata nome
. Ecco come apparirà la nostra classe:
package com.asfusion.helloworld.mate.events { import flash.events.Event; public class HelloWorldEvent extends Event { public static const GET:String = "getHelloWorld"; public function HelloWorldEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false) { super(type, bubbles, cancelable); } } }
Per quanto riguarda gli eventi siamo a posto. Ora tocca alle mappe, in modo tale da dare un ordine al tutto. Nella cartella “maps" creiamo un nuovo MXML Component. Chiamiamolo “MainEventMap" e non specifichiamo le sue dimensioni, dato che comunque non sarà un componente visibile bensì prettamente logico. Adesso possiamo iniziare a scrivere un po' di codice all'interno di questa mappa. Nel caso non vi siano ben chiari i tag che saranno presenti, ricontrollate la sezione teorica precedente. Molto probabilmente ci ritroveremo davanti un codice del genere:
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</mx:Canvas>
Modifichiamolo in quello che potete vedere dal listato successivo, eliminando gli ultimi due attributi del tag principale e modificando il tag mx:Canvas
in EventMap. Dopodiché, oltre alla rimozione del tag declarations
, dovremo provvedere ad aggiungere il namespace relativo a Mate (http://mate.asfusion.com/):
<?xml version="1.0" encoding="utf-8"?>
<mate:EventMap xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mate="http://mate.asfusion.com/">
</mate:EventMap>
Adesso possiamo fare ancora un passo avanti. Dobbiamo inserire il tag EventHandlers
legato al nostro evento “HelloWorldEvent" e gestirlo di conseguenza. Come abbiamo visto prima nella sezione teorica, per ogni evento da gestire c'è un tag EventHandlers
. Dopodiché, al suo interno, si specificano i vari tag da usare in base a come decidiamo di gestire la situazione. Per quanto riguarda questo webservice in PHP, useremo il tag RemoteObjectInvoker
. Ecco come appare il nostro codice dopo la modifica.
<EventMap xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mate="http://mate.asfusion.com/">
<fx:Script>
<![CDATA[
import com.asfusion.helloworld.mate.events.HelloWorldEvent;
]]>
</fx:Script>
<EventHandlers type="{HelloWorldEvent.GET}">
<RemoteObjectInvoker
source=""
destination=""
method=""
arguments="">
<!--<resultHandlers>
</resultHandlers>
<faultHandlers>
</faultHandlers>-->
</RemoteObjectInvoker>
</EventHandlers>
</EventMap>
Abbiamo aggiunto, nel tag fx:script
, la direttiva di import per il nostro evento HelloWorldEvent
. A quel punto abbiamo realizzato l'EventHandler specificando in type
l'evento del quale avevamo bisogno: HelloWorldEvent.GET
(vi ricordate la costante di tipo string che abbiamo creato prima?). Poi abbiamo creato il tag RemoteObjectInvoker
, con gli attributi di cui necessita: source
, destination
, method
, arguments
. Questi per ora lasciateli così, vuoti: presto spiegheremo a cosa servono e quindi come completarli. Abbiamo inoltre aggiunto altri due tag: resultHandlers
e faultHandlers
. Il nome già può suggerire a cosa servono, ma presto vedremo anche loro nel dettaglio.
Prima di tornare ad avere a che fare con la nostra EventMap, infatti, dobbiamo dedicarci a quella che sarà la “facciata" che ci permetterà di interagire con l'utente. Aggiungiamo quindi al nostro progetto un nuovo MXML Component, precisamente sotto la cartella “views" precedentemente creata. Il nome sarà “HelloWorldPanel" e sarà, come il nome suggerisce, un componente ereditato dalla classe Panel
. Cliccate ora su 'Finish' ed iniziamo la modifica visuale. Aggiungete una label, un pulsante (button) ed un casella di testo nella quale inserire il nostro nome. Qualcosa molto simile a quello che vedete in figura:
Adesso, cliccando sul pulsante dedicato alla creazione di un nuovo stato per il nostro componente, realizziamo un nuovo stato chiamato “risultato". La differenza tra i due è semplice: avremo il primo in fase di inserimento del nome nella TextBox. Dopo aver cliccato sul pulsante per inviare le informazioni al WebService, passeremo allo stato risultato che si occuperà di restituire il risultato. Lavorando in questo nuovo stato, creiamo un'altra Label. Ecco come si presenterà adesso in modalità “Design" la nostra creazione:
Ora che abbiamo visto velocemente il design dell'interfaccia, passiamo subito al codice. Qui non seguiremo la cosa passo per passo: riporto tutto il codice della schermata spiegando mano a mano quello che è stato fatto.
<?xml version="1.0" encoding="utf-8"?>
<s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="454" height="148" height.risultato="130"
title="Hello World Mate!"
resizeEffect="Resize" xmlns:mate="http://mate.asfusion.com/">
<fx:Script>
<![CDATA[
import com.asfusion.mate.events.ResponseEvent;
import mx.rpc.events.ResultEvent;
private function inviaNome():void
{
dispatcher1.generateEvent();
}
private function handleResult(event:ResponseEvent):void
{
currentState = "risultato";
res_servizio.text = event.result.toString();
}
private function handleFault(event:ResponseEvent):void
{
currentState = "risultato";
res_servizio.text = event.fault.faultString;
}
]]>
</fx:Script>
<s:states>
<s:State name="State1"/>
<s:State name="risultato"/>
</s:states>
<fx:Declarations>
<mate:Dispatcher id="dispatcher1" generator="com.asfusion.helloworld.mate.events.HelloWorldEvent" type="{com.asfusion.helloworld.mate.events.HelloWorldEvent.GET}">
<mate:eventProperties>
<mate:EventProperties nome="{nomeinput.text}"/>
</mate:eventProperties>
<mate:ServiceResponseHandler result="handleResult(event)" fault="handleFault(event)" />
</mate:Dispatcher>
</fx:Declarations>
<s:Label x="10" y="10" text="Insert Name:"/>
<s:TextInput id="nomeinput" x="10" y="30" width="338"/>
<s:Button x="356" y="29" label="Button" width="87" height="23" click="inviaNome();"/>
<s:Label id="res_servizio" includeIn="risultato" x="10" y="73" text="risultato" width="432"/>
</s:Panel>
Non fatevi spaventare dalla mole di novità. Ricapitoliamo velocemente quello che farà la nostra applicazione, per avere le idee più chiare. Nella nostra interfaccia inseriremo un nome, sotto forma di stringa. Ci troviamo nella “view". La pressione del pulsante scatenerà un evento che abbiamo già realizzato, nella classe “HelloWorldEvent". A gestire i dovuti collegamenti ci pensa la nostra EventMap. La stringa data in input verrà quindi trasferita al servizio web, che la elaborerà per restituirci il risultato: un “Hello World! Hi (nome)" nel caso abbiamo specificato un nome, altrimenti un “What's your name?" nel caso la stringa sia arrivata vuota.
Ed eccoci arrivati al codice.
La prima riga non ha bisogno di spiegazioni: è la dichiarazione del formato del nostro file (un semplice file xml). Le righe successive (dalla 2 alla 6) introducono il tag “Panel” con tutti i namespace da utilizzare (sono definiti in maniera standard) e alcune opzioni riguardanti il titolo, la grandezza e l'eventuale animazione da usare in fase di ridimensionamento. La sezione successiva racchiude i tre metodi che usiamo nel contesto della nostra applicazione. Uno serve a gestire l'input, altri due per gestire l'output. Tutti e tre sono di tipo “void”.
Il tag states
descrive i due stati nei quali il componente potrà trovarsi. Quello base, di partenza, chiamato 'State1' e quello nel quale viene fuori il risultato dell'elaborazione del WebService, 'risultato'. Ci troviamo tra la riga 32 e 35. Dalla riga 37 alla 46 abbiamo un pezzo di codice decisamente importante: racchiuso tra il tag Declarations
troviamo infatti il Dispatcher, elemento essenziale nel funzionamento del tutto. Il suo compito, infatti, è quello di dare il via all'evento in base a determinate condizioni. Al suo interno troviamo due tag. eventProperties
, che prende come proprietà da usare il nome specificato nella TextBox, e ServiceResponseHandler
invece richiama gli ultimi due metodi citati sopra: handleResult
ed handleFault
.
È stato specificato un id ben preciso per questo tag: dispatcher1
. Ecco quindi che ci possiamo ricollegare al primo metodo precedentemente menzionato, inviaNome()
. Tutto quello che fa infatti è richiamare il metodo generateEvent
dell'oggetto dispatcher1
.
Ma da cosa è richiamato questo dispatcher? Ecco che arriviamo all'ultima sezione del codice del nostro file. Le ultime quattro righe, escludendo il tag di chiusura del Panel, servono a definire i componenti grafici che abbiamo creato poco fa in fase di Design. Il pulsante, le label, la casella di testo. La casella di testo e la label più in basso (presente solo nel secondo stato) hanno degli id precisi, dato che devono essere richiamati in fase di codice. Rispettivamente sono “nomeinput” e “res_servizio”. Il pulsante, invece, ha un handler legato all'evento “click”. È proprio da qui che richiamiamo il metodo inviaNome()
.
Il dispatcher, arrivato a questo punto, avvia tutta la procedura. Tramite la EventMap risaliamo a quelli che sono i compiti del nostro programma, e tramite le istruzioni fornite nella map stessa ci colleghiamo al servizio web. Ecco qui di seguito il listato completo del codice della EventMap, contenuta nel file precedentemente creato MainEventMap.mxml.
<?xml version="1.0" encoding="utf-8"?>
<mate:EventMap xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mate="http://mate.asfusion.com/">
<fx:Script>
<![CDATA[
import com.asfusion.helloworld.mate.events.HelloWorldEvent;
]]>
</fx:Script>
<fx:Declarations>
<mate:EventHandlers type="{HelloWorldEvent.GET}">
<mate:RemoteObjectInvoker
source="mateTest1.WebServiceTest"
destination="amfphp"
method="helloWorld"
arguments="{event.nome}">
<mate:resultHandlers>
<mate:ServiceResponseAnnouncer type="result"/>
</mate:resultHandlers>
<mate:faultHandlers>
<mate:ServiceResponseAnnouncer type="fault"/>
</mate:faultHandlers>
</mate:RemoteObjectInvoker>
</mate:EventHandlers>
</fx:Declarations>
</mate:EventMap>
Sono cambiate un po' di cose rispetto alla nostra ultima modifica: vediamo quali. Innanzitutto, abbiamo l'inclusione di un tag Script
per eseguire una import. Precisamente, la import riguarda l'evento da usare che abbiamo creato precedentemente: l'HelloWorldEvent.
Dopo questo richiamo, abbiamo aggiunto il tag EventHandlers
completandolo con le dovute istruzioni. Utilizzando AMFPHP ed un servizio web abbiamo usato un RemoteObjectInvoker
con i seguenti parametri: source
, destination
, method
, arguments
. source
serve a designare la classe del servizio che vogliamo usare: in questo caso abbiamo a che fare con la classe WebServiceTest
contenuta nella cartella “mateTest1”. La stringa da inserire sarà “mateTest1.WebServiceTest”. Tocca quindi alla destination
, dove dovremo specificare la stringa “AMFPHP”. I successivi due attributi sono di facile comprensione: in method
andrà il nome del metodo da usare (“helloWorld”) e in arguments
invece il nome dell'argomento da passare al metodo. In questo caso dovremo usare {event.nome}
, la variabile definita nel file HelloWorldEvent.as.
Ormai abbiamo finito, manca solo l'ultimo passo. Vi ricordate il file “services-config.xml” creato tempo fa? Bene, è arrivato il momento di includerlo nelle opzioni di compilazione, altrimenti il nostro client non riuscirà a comunicare con il WebService. Cliccate con il pulsante destro del mouse sulla cartella principale del nostro progetto nel Package Explorer. Selezionate la voce “Properties” e successivamente la scheda “Flex Compiler”. Modificate il valore “Additional compiler arguments” come vedete in figura:
Ed anche questo ultimo step è andato. Ricontrollate bene le procedure e assicuratevi di avviare il server in locale prima di avviare il nostro client. Cliccate su “Run” e l'applicazione dovrebbe avviarsi automaticamente nel browser predefinito. Qui di seguito ecco qualche schermata delle prove effettuate.
Sono disponibili per il download tutti i file del progetto.