Académique Documents
Professionnel Documents
Culture Documents
AMADOU DIAW
CONCEPTEUR/ DEVELOPPEUR
DE
SYSTEMES D’INFORMATIONS
Email : jodyama@hotmail.com
INTRODUCTION
Flex est un Framework qui sert à la création d’interfaces client riches (front end de
l’application) basé sur l’usage de la technologie Adobe Flash. En effet, si celle-ci apporte une
grande souplesse pour la création d’interfaces graphiques riches, elle est souvent perçue par
les non-initiés comme complexe.
De plus, pour bon nombre de techniciens spécialisés dans le développement d’application, la
conception et la réalisation de l’interface graphique de l’application semblent souvent
secondaires : ils préfèrent se focaliser complètement sur la fonctionnalité à développer plutôt
que sur la présentation du résultat. Le Framework Flex a ainsi pour objectif de faciliter cette
partie du développement.
Fonctionnement
Une application Flex n’est autre qu’un fichier portant l’extension .swf (ShockWave Flash)
issu de la compilation de fichiers MXML et ActionScript, insérés dans une page web.
Une application peut être divisée en plusieurs couches ou tiers applicatifs, nous parlons alors
d’une architecture n-tiers. Ainsi, si nous subdivisons une application en trois couches
distinctes, nous obtenons une architecture 3-tiers :
La couche Présentation est chargée, comme son nom l’indique, de présenter les
données (interface Homme-Machine ou IHM).
La couche Métier implémente la logique métier (règle de gestion, etc.).
La couche d’accès aux données réalise la tâche de persistance des données (stockage)
via l’utilisation d’une base de données, par exemple.
Chaque couche propose des services qu’elle met à disposition de la couche qui lui est
directement supérieure. Ainsi, la couche la plus élevée ne peut communiquer avec la couche
la plus basse de l’architecture que par la couche intermédiaire, comme l’illustre la figure
suivante :
I. Le langage MXML
MXML est un langage basé sur XML permettant de décrire les interfaces graphiques, de
définir les états dans l’interface, de modéliser des effets de transition et d'insérer du code
comportemental.
Une page MXML ressemble à ceci :
La ligne (1) correspond à du vrai XML et constitue la première ligne d'un document
MXML.
La ligne (2) montre que le conteneur principal de l'application déclare l'espace de
nommage (namespace), qui permet d'utiliser les composants natifs de Flex
La ligne (5) est l'espace dédié à l'ajout d'éléments graphiques grâce à des balises.
La ligne (6) permet de fermer la balise du conteneur principal de l'application.
Une balise MXML représente un composant graphique qui peut être un conteneur (de type
boite, panneau, fenêtre,…) ou un élément de contrôle (de type champ de texte, liste, bouton,
…) et comportes trois types d’attributs :
Propriétés (id, width, height, label)
Style
Evénements (click, enter…)
Quelques exemples
II. Le langage ActionScript
ActionScript ( AS ) est un langage de script orienté objet permettant aussi bien de créer des
composants dynamiquement et de les ajouter à l'application que de traiter des chaînes de
caractères, d'ajouter des écouteurs d'événements ( EventListener ) ou de gérer les
échanges client/serveur notamment par le chargement de fichiers ou la communication avec
un langage serveur. Etant basé sur ECMAScript, version standardisée de JavaScript,
ActionScript et JavaScript partagent une syntaxe semblable.
Afin que vous puissiez lire facilement les extraits de code ActionScript présents dans ce
tutoriel, nous avons jugé bon de vous apporter les bases de ce langage en abordant des
notions communes à tout apprentissage d’un nouveau langage :
les variables ;
les boucles et les conditions ;
les procédures et les fonctions ;
1) Les variables
Les variables permettent de stocker des informations en vue de les utiliser dans divers
traitements.
Une variable est déclarée par un nom précédé de la mention var. Il est également
indispensable de spécifier le type de la variable déclarée :
var nomVariable:type
Exemple
Tableau de variables
2) Les boucles et les conditions
Les boucles permettent de réaliser un traitement sur un nombre d’itérations prédéfinis.
Exemple
Les conditions
Exemple de fonction
Nous avons donc abordé les notions essentielles pour pouvoir débuter un projet Flex.
Le langage ActionScript étant souple ainsi que le langage MXML du point de vu
présentation, nous vous proposons de mettre en place une application Flex de type CRUD
pour compléter votre formation.
Partie 1 : Simple Application Flex
Cliquer sur FichierNouveauProjet Flex
On a donc :
un formulaire, dans lequel on trouve quatres textInput , un ComboBox, un bouton
valider.
Un Datagrid : Après avoir cliqué et glissé le Datagrid dans la page, vous pouvez
configure les colonnes du Datagrid en cliquant le bouton droit sur le Datagrid,
configurer les colonnes.
Trois boutons : Nouveau, Modifier et Supprimer
Chaque élément doit avoir un identifiant, c’est grace à cet identifiant que vous pouvez
manipuler ce composant, comme récupérer son contenu, ou bien le mettre à jour.
Exemple d’identifiants : nomTextInput, nouveauButton, etudiantGrid.
Maintenant que le module etudiant est terminé, comment demander au parentApplication de
le charger.
Revenez au fichier « Main.MXML »
Et aller en mode création.
Modifier sa largeur à 1024 et la hauteur à 700.
Glissez un composant moduleLoader dans la page et étirez le pour qu’il prenne toute la page.
Le moduleLoader comme on l’entend est le chargeur de module, il faut donc lui préciser l’url
du module à charger.
Chaque module créé génére un fichier swf et c’est donc ce fichier qui sera chargé
On lui donne un identifiant « moduleLoader »
Et l’url du module à charger « etudiant.swf »
Sauvegarder la page, vous remarquez automatiquement, que le module est chargé dans la
page.
Il ne reste plus qu’à lancer l’application
Le code du Main.MXML devient :
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication 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="1024" height="700">
<fx:Declarations>
<!-- Placer ici les éléments non visuels (services et objets de
valeur, par exemple). -->
</fx:Declarations>
<mx:ModuleLoader x="0" y="0" width="1015" height="690"
id="moduleLoader" url="etudiant.swf">
</mx:ModuleLoader>
</s:WindowedApplication>
Un clic sur la flèche verte exécute l’application.
Et voilà ce que ça donne.
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="1024" height="700" applicationComplete="init()">
<fx:Script>
<![CDATA[
public function init():void
{
moduleLoader.loadModule("etudiant.swf");
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Placer ici les éléments non visuels (services et objets de
valeur, par exemple). -->
</fx:Declarations>
<mx:ModuleLoader x="0" y="0" width="1015" height="690"
id="moduleLoader">
</mx:ModuleLoader>
</s:WindowedApplication>
On a écrit une fonction init() :void, et on demande à cette fonction de charger le module
etudiant.swf
moduleLoader.loadModule("etudiant.swf");
Mais là nous avons seulement écrit le corps de la fonction.
On doit donc demander à l’application d’exécuter cette fonction au démarrage.
<s:WindowedApplication 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="1024" height="700" applicationComplete="init()">
applicationComplete=”fonctionAExecuter()”
NB: Très important
Si une application doit exécuter une fonction au démarrage
applicationComplete=”fonctionAExecuter()”
Si un module doit exécuter une fonction au démarrage
creationComplete=”fonctionAExecuter()”
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Placer ici les éléments non visuels (services et objets de
valeur, par exemple). -->
</fx:Declarations>
<mx:Form x="52" y="27" width="270" height="198">
<mx:FormItem label="Nom">
<s:TextInput id="nomTextInput"/>
</mx:FormItem>
<mx:FormItem label="Prénom">
<s:TextInput id="prenomTextInput"/>
</mx:FormItem>
<mx:FormItem label="Adresse">
<s:TextInput id="adresseTextInput"/>
</mx:FormItem>
<mx:FormItem label="Nationalité">
<s:TextInput id="nationaliteTextInput"/>
</mx:FormItem>
<mx:FormItem label="Classe">
<s:ComboBox id="classeComboBox"/>
</mx:FormItem>
<s:Button label="Valider" id="validerButton"
click="OnValiderButtonClick()"/>
</mx:Form>
<mx:DataGrid x="52" y="229" width="545" height="182"
id="etudiantGrid">
<mx:columns>
<mx:DataGridColumn headerText="Nom" dataField="nom"/>
<mx:DataGridColumn headerText="Prenom"
dataField="prenom"/>
<mx:DataGridColumn headerText="Adresse"
dataField="adresse"/>
<mx:DataGridColumn dataField="nationalite"
headerText="Nationalite"/>
<mx:DataGridColumn dataField="classe"
headerText="Classe"/>
</mx:columns>
</mx:DataGrid>
<s:Button x="54" y="413" label="Nouveau" id="nouveauButton"/>
<s:Button x="129" y="413" label="Modifier" id="modifierButton"/>
<s:Button x="203" y="413" label="Supprimer" id="supprimerButton"/>
</mx:Module>
Pourquoi [Bindable] ?
Il faut rappeler que Flex est basé sur la programmation évènementielle; grâce au binding,
une variable peut être lié automatiquement entre des sources et des cibles, c'est-à-dire qu’à
chaque changement de valeur d'une variable, celle-ci est mise à jour automatiquement dans le
composant qu'il l'utilise.
Dans notre cas, puisque notre collection est source d’alimentation de notre ComboBox, il faut
le binder pour qu’à chaque modification de la collection, le changement se répercute
directement sur le comboBox.
Il faut donc préciser à la collection que ses données doivent provenir de cette collection
<s:ComboBox id="classeComboBox" dataProvider="{classesList}"/>
Chaque ComboBox possède un attribut « label »
etudiantsList.addItem({id:1,nom:"DIAW",
prenom:"Amadou",
adresse:"Dakar",
nationalite:"MAURITANIENNE",
classe:"TEK2"});
etudiantsList.addItem({id:2,nom:"DIAW",
prenom:"Abdoulaye",
adresse:"Saint-Louis",
nationalite:"SENEGALAISE",
classe:"TEK1"});
etudiantsList.addItem({id:1,nom:"DIAW",
prenom:"Amadou",
adresse:"Dakar",
nationalite:"MAURITANIENNE",
classe:"TEK2"});
}
La fonction addItem ajoute une ligne à la collection
etudiantsList.addItem({id:1,nom:"DIAW",
prenom:"Amadou",
adresse:"Dakar",
nationalite:"MAURITANIENNE",
classe:"TEK2"});
etudiantsList.addItem({id:2,nom:"DIAW",
prenom:"Abdoulaye",
adresse:"Saint-
Louis",
nationalite:"SENEGALAISE",
classe:"TEK1"});
etudiantsList.addItem({id:1,nom:"DIAW",
prenom:"Amadou",
adresse:"Dakar",
nationalite:"MAURITANIENNE",
classe:"TEK2"});
}
public function OnValiderButtonClick():void
{
// Déclaration de quatres variables de Type String
var v_nom:String;
var v_prenom:String;
var v_adresse:String;
var v_nationalite:String;
// la varibale v_nom recupere le texte saisie dans
nomTextInput
v_nom=nomTextInput.text;
// la varibale v_prenom recupere le texte saisie
dans prenomTextInput
v_prenom=prenomTextInput.text;
// la varibale v_adresse recupere le texte saisie
dans adresseTextInput
v_adresse=adresseTextInput.text;
// la varibale v_nationalite recupere le texte
saisie dans nationaliteTextInput
v_nationalite=nationaliteTextInput.text;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Placer ici les éléments non visuels (services et objets de
valeur, par exemple). -->
</fx:Declarations>
<mx:Form x="52" y="27" width="270" height="198">
<mx:FormItem label="Nom">
<s:TextInput id="nomTextInput"/>
</mx:FormItem>
<mx:FormItem label="Prénom">
<s:TextInput id="prenomTextInput"/>
</mx:FormItem>
<mx:FormItem label="Adresse">
<s:TextInput id="adresseTextInput"/>
</mx:FormItem>
<mx:FormItem label="Nationalité">
<s:TextInput id="nationaliteTextInput"/>
</mx:FormItem>
<mx:FormItem label="Classe">
<s:ComboBox id="classeComboBox"
dataProvider="{classesList}"/>
</mx:FormItem>
<s:Button label="Valider" id="validerButton"
click="OnValiderButtonClick()"/>
</mx:Form>
<mx:DataGrid x="52" y="229" width="545" height="182"
id="etudiantGrid" dataProvider="{etudiantsList}">
<mx:columns>
<mx:DataGridColumn headerText="Nom" dataField="nom"/>
<mx:DataGridColumn headerText="Prenom"
dataField="prenom"/>
<mx:DataGridColumn headerText="Adresse"
dataField="adresse"/>
<mx:DataGridColumn dataField="nationalite"
headerText="Nationalite"/>
<mx:DataGridColumn dataField="classe"
headerText="Classe"/>
</mx:columns>
</mx:DataGrid>
<s:Button x="54" y="413" label="Nouveau" id="nouveauButton"/>
<s:Button x="129" y="413" label="Modifier" id="modifierButton"/>
<s:Button x="203" y="413" label="Supprimer" id="supprimerButton"/>
</mx:Module>
Vous remarquez que dans creationComplete on indique la fonction init(), puisqu’il s’agit
d’un module.
Ce qui donne
v_prenom=prenomTextInput.text;
v_adresse=adresseTextInput.text;
v_nationalite=nationaliteTextInput.text;
v_classe=classeComboBox.selectedItem["label"];
taille=etudiantsList.length;
etudiantsList.addItem({id:(taille+1),nom:v_nom,
prenom:v_prenom,
adresse:v_adresse,
nationalite:v_nationalite,
classe:v_classe});
}
On récupère le label de la classe sélectionnée par
v_classe=classeComboBox.selectedItem["label"];
On calcule la longueur de la liste
taille=etudiantsList.length;
(taille+1) représentera l’id d’un étudiant
v_adresse=etudiantGrid.selectedItem["adresse"];
v_nationalite=etudiantGrid.selectedItem["nationalite"];
v_classe=etudiantGrid.selectedItem["classe"];
Alert.show("Nom: "+v_nom+" Prénom:
"+v_prenom+" Adresse: "+v_adresse+" Nationalité: "+v_nationalite+" Clase:
"+v_classe);
}
}
Il ne reste plus qu’à l’associer au itemClick sur le Datagrid
<mx:DataGrid x="52" y="229" width="545" height="182" id="etudiantGrid"
dataProvider="{etudiantsList}"
itemClick="OnGridEtudiantClick(event)">
Ce qui donne
v_classe=classeComboBox.selectedItem["label"];
Alert.show("Vous etes en :"+v_classe);
}
}
Maintenant, il faut l’associer à la close du ComboBox
<s:ComboBox id="classeComboBox" dataProvider="{classesList}"
close="OnClasseComboBoxClose(event)"/>
Ce qui met fin à la première partie de notre tutoriel.
Partie2 : Communication entre Flex, PHP et MySQL
Dans cette partie, nous allons apprendre comment échanger des données entre Flash (AS3)
et Php / MySQL.
Qu’est-ce que le Flash Remoting ?
Le Flash Remoting permet des échanges entre un client (flash) et un serveur (php). De plus, il
possède un format de données propre : l’AMF pour Action Message Format.
Flash Remoting fonctionnait au départ avec Coldfusion pour la partie serveur.
Très rapidement pour que des langages serveurs tels PHP, PERL, .NET puissent utiliser le
format AMF, différents projets AMF ont vu le jour, permettant alors d’interfacer des
langages serveurs comme PHP, .NET, avec le lecteur Flash. AMFPHP, s’est établi comme un
standard dans la communauté Flash/Flex.
Le tableau suivant récapitule les différents projets AMF existants :
Lorsque vous développez aujourd’hui un projet Flex avec des échanges serveurs, vous avez
par exemple la possibilité d’utiliser le format XML avec la classe HTTPRequest.
En réalité vous échangez entre le serveur et votre client Flex une chaîne de caractères que ce
soit pour le XML ou SOAP. Ne serait-il pas plus pratique de pouvoir échanger, sans aucun
traitement de votre part, tous les types ActionScript entre votre serveur et votre application
Flex ?
Ces projets AMF vont automatiquement sérialiser les données échangées. Vous envoyez un
type Boolean, ce projet, que l’on appellera « passerelle », va alors détecter ce type et le
convertir en type compatible côté serveur.
Vous envoyez un type Array vers votre service, le projet AMF convertira automatiquement
ce tableau en tableau compatible pour le langage utilisé côté serveur. Prenons l’exemple
d’AMFPHP.
Dans votre application Flex tout objet envoyé vers votre service PHP sera sérialisé en type.
Dans ce TP nous utiliserons la librairie AMFPHP
Dans votre application Flex tout objet envoyé vers votre service PHP sera sérialisé en type
correspondant PHP.
Fonctionnement d’AMFPHP
AMFPHP va servir d’intermédiaire entre le code serveur et l’application Flex, tous les
échanges passeront par AMFPHP qui se chargera de toute la sérialisation.
Pour vous procurer AMFPHP il vous suffit de vous rendre sur le site du projet à l’adresse
suivante http://www.amfphp.org.
Débutons à présent notre TP
Copier d’abord le dossier AMFPHP dans le répertoire de votre projet
C:\wamp\www\ApplicationFlexBD
Il y a 2 dossiers et 1 fichier important :
browser : permet de tester vos services Php.
services : contient les Services Php ou classes de communication avec une base de
données MySQL.
gateway.php : la passerelle à configurer dans votre fichier ActionScript pour lancer la
communication de Flash avec Php.
Ensuite, tapez l’url d’accès la passerelle gateway.php
http://localhost/Application%20Flex/amfphp/gateway.php
Cliquer sur le lien « Load the service browser » et cliquer sur « Save »
Créer ensuite une base de donées base_tp_flex
Créer ensuite les tables : « etudiant » et « classe »
Toutes les classes que nous allons créer hériteront de cette classe, car pour dialoguer avec une
base de données il faut d’abord se connecter.
Créer ensuite la classe Etudiant.php
Le fichier Classe.php
package
{
import flash.net.NetConnection;
import flash.net.ObjectEncoding;
public class RemotingConnection extends NetConnection
{
public function RemotingConnection( sURL:String )
{
objectEncoding = ObjectEncoding.AMF0;
if(sURL) connect( sURL );
}
public function AppendToGatewayUrl( s : String ) : void
{
//
}
}
}
Ouvrez le fichier général de l’application : le Main.mxml
Dans ce fichier, on va déclarer une variable de type RemotingConnection
On instancie dans la fonction init() en précisant l’url de notre browser
Donc tous les fichiers de l’application pourront utiliser cette variable pour utiliser les services
PHP.
La fonction OnFault nous renvoie les erreurs de l’application dans un Alert.
Il faut donc rappeler que pour appeler une service, on utilisera un Responder qui prend deux
paramètres : la fonction qui récupère le résultat du service, et la fonction qui sera exécutée en
cas d’erreur.
La fonction qui récupère le résultat a en paramètre ce que retourne le service, c’est-à-dire si le
service retourne un tableau, la fonction reçoit en paramètre ce tableau, si c’est un String la
fonction reçoit un String.
Une variable etudiant_id qui est initialisé à -1 , donc cette valeur changera de valeur dès
qu’un étudiant sera sélectionné, il prendra comme valeur l’id de cet étudiant et s’il n’ya pas
d’étudiant sélectionné cette variable reçoit comme valeur -1.
De même que la variable filire_id
Donc pour accéder a ces variables dans les autres fichiers de l’application
parentApplication.etudiant_id
parentApplication.filiere_id
Notre fonction init() changera, car si l’application démarre on veut afficher tous les étudiants
dans la base de données dans le dataGrid et les filières aussi dans le comboBox.
On appellera don les services Etudiant. listEtudiants et Classe. getClasses
parentApplication.gateway.call("Classe.getClasses", new
Responder(OnGetClassesResult, parentApplication.onFault));
}
Cette fonction recupère les résultats envoyès par le service et ajoute les données à la
collection etudiantsList
public function OnListEtudiantResult(result:Array):void
{
var i:int;
if(!etudiantsList)
etudiantsList=new ArrayCollection();
else
etudiantsList.removeAll();
for(i=0;i<result.length;i++)
etudiantsList.addItem({
id:result[i]["id"],
nom:result[i]["nom"],
prenom:result[i]["prenom"],
adresse:result[i]["adresse"],
nationalite:result[i]["nationalite"],
classe_id:result[i]["classe_id"]});
}
Il faut donc modifier le datafield de la colonne Classe dans le Datagrid, On mettra donc
classe_id.
<mx:DataGrid x="52" y="229" width="545" height="182" id="etudiantGrid"
dataProvider="{etudiantsList}"
itemClick="OnGridEtudiantClick(event)">
<mx:columns>
<mx:DataGridColumn headerText="Nom" dataField="nom"/>
<mx:DataGridColumn headerText="Prenom"
dataField="prenom"/>
<mx:DataGridColumn headerText="Adresse"
dataField="adresse"/>
<mx:DataGridColumn dataField="nationalite"
headerText="Nationalite"/>
<mx:DataGridColumn dataField="classe_id"
headerText="Classe"/>
</mx:columns>
</mx:DataGrid>
Cette fonction recupère les résultats envoyès par le service et ajoute les données à la
collection
classesList
public function OnGetClassesResult(result:Array):void
{
var i:int;
if(!classesList)
classesList=new ArrayCollection();
else
classesList.removeAll();
for(i=0;i<result.length;i++)
classesList.addItem({
id:result[i]["id"],
label:result[i]["acronyme"],
nomclasse:result[i]["nomclasse"]}
);
}
Nous allons maintenant modifier notre function OnValiderButtonClick()
Cette fonction doit enregistrer les informations saisies dans la table etudiant
public function OnValiderButtonClick():void
{
// Déclaration de quatres variables de Type String
var taille:int;
var v_nom:String;
var v_prenom:String;
var v_adresse:String;
var v_nationalite:String;
var v_classe_id:int;
// la varibale v_nom recupere le texte saisie dans
nomTextInput
v_nom=nomTextInput.text;
// la varibale v_prenom recupere le texte saisie
dans prenomTextInput
v_prenom=prenomTextInput.text;
// la varibale v_adresse recupere le texte saisie
dans adresseTextInput
v_adresse=adresseTextInput.text;
// la varibale v_nationalite recupere le texte
saisie dans nationaliteTextInput
v_nationalite=nationaliteTextInput.text;
v_classe_id=classeComboBox.selectedItem["id"];
parentApplication.gateway.call("Etudiant.addEtudiant",new
Responder(OnAddEtudiantResult,parentApplication.onFault),
v_nom,v_prenom,v_adresse,v_nationalite,v_classe_id);
}
parentApplication.gateway.call("Etudiant.listEtudiants", new
Responder(OnListEtudiantResult, parentApplication.onFault));