Apache Adobe Flex TutorialTutoriaux Adobe Flex & AIR en Français

25juin/0818

Flex HTTPService – HTTPService en ActionScript, Remote Proxy

Bien que la façon la plus simple et la plus rapide d'utiliser l'objet HTTPService est de le créer en MXML, cette technique est préférable pour les applications non-entreprise dans lesquels les scénarios de communication sont assez simples. Cependant, pour des applications ayant des exigences plus importantes, il est préférable d'utiliser les remote proxies. Puisque les composants HTTPService proposent de grands avantage d'un point de vue conversion de données (comme la sérialisation de data), c'est une bonne idée d'utiliser un objet HTTPService à l'intérieur d'un remote proxy. Cependant, il est généralement nécessaire de travailler ensuite avec le composant HTTPService entièrement en ActionScript, y compris la construction de l'objet et la récupération des réponses.

Si vous travaillez avec des objets HTTPService entièrement en ActionScript, vous devrez importer la classe mx.rpc.http.HTTPService. Vous pouvez ensuite en construire une nouvelle instance en utilisant l'instruction "new":

var httpService:HTTPService = new HTTPService();

Vous pouvez ensuite fixer la propriété "url":

httpService.url = "data.txt";

Tout comme vous écouteriez les événements d'un objet, vous avez besoin d'ajouter des listeners aux objets HTTPService en utilisant addEventListener(). Les objets HTTPService lancent des événements de type ResultEvent quand une réponse est retournée, et ils lancent des événements de type FaultEvent quand une erreur est retournée par le serveur. Les classes ResultEvent et FaultEvent sont dans le package mx.rpc.events.package:

httpRequest.addEventListener(ResultEvent.RESULT, resultHandler);

L'exemple suivant utilise l'approche recommandée des remote proxy en conjonction avec HTTPService. Cet exemple accomplit la même chose que le tutorial Flex HTTPService - Envoyer des paramètres avec la propriété request qui est lui fait en MXML. Cependant cet exemple utilise plusieurs classes pour le faire.

La première classe est une simple classe modèle de donnée appelée ApplicationDataModel.as:

package{
	import mx.collections.ListCollectionView;

	public class ApplicationDataModel{

		private static var _instance:ApplicationDataModel;

		private var _countryNames:ListCollectionView;
		private var _statesNames:ListCollectionView;

		[Bindable]
		public function set countryNames(value:ListCollectionView):void{
			_countryNames = value;
		}

		public function get countryNames():ListCollectionView{
			return _countryNames;
		}

		[Bindable]
		public function set statesNames(value:ListCollectionView):void{
			_statesNames = value;
		}

		public function get statesNames():ListCollectionView{
			return _statesNames;
		}	

		public function ApplicationDataModel(){}

		public static function getInstance():ApplicationDataModel{
			if(_instance == null){
				_instance = new ApplicationDataModel();
			}
			return _instance;
		}
	}
}

Dans l'extrait de code suivant, on définit StatesService, qui est le remote proxy qui charge la donnée XML en utilisant HTTPService. Cette classe définit deux méthodes de service: getCountries() et getStates(). Quand les résultats sont retournés par l'appel au service, ils sont assignés au modèle de donnée:

 package{

	import mx.rpc.http.HTTPService;
	import mx.rpc.events.ResultEvent;
	import mx.collections.ListCollectionView;
	import ApplicationDataModel;
	import mx.collections.XMLListCollection;

	public class StatesService{

		private var _service:HTTPService;

		public function StatesService(){
			_service = new HTTPService();
			_service.resultFormat= "e4x";
		}

		public function getCountries():void{
			_service.addEventListener(ResultEvent.RESULT, countriesResultHandler);
			_service.url = "http://www.rightactionscript.com/states/xml/countries.xml";
			_service.send();
		}

		public function getStates(country:String):void{
			_service.addEventListener(ResultEvent.RESULT, statesResultHandler);
			_service.url = "http://www.rightactionscript.com/states/xml/states.php?country="+country;
			_service.send();
		}

		public function countriesResultHandler(event:ResultEvent):void{
			_service.removeEventListener(ResultEvent.RESULT, countriesResultHandler);
			ApplicationDataModel.getInstance().countryNames = new XMLListCollection(_service.lastResult.children() as XMLList);
		}

		public function statesResultHandler(event:ResultEvent):void{
			_service.removeEventListener(ResultEvent.RESULT, statesResultHandler);
			ApplicationDataModel.getInstance().statesNames = new XMLListCollection(_service.lastResult.children() as XMLList);
		}

	}
}

Et enfin, l'application MXML qui utilise ces deux classes:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
	verticalAlign="middle" horizontalAlign="center"
	creationComplete="creationCompleteHandler(event)" viewSourceURL="srcview/index.html">
	<mx:Script>
		<![CDATA[
			import mx.rpc.http.HTTPService;
			import mx.rpc.events.ResultEvent;

			private var _statesService:StatesService;

			private function creationCompleteHandler(event:Event):void{
				_statesService = new StatesService();
				_statesService.getCountries();
			}
		]]>
	</mx:Script>

	<mx:Panel title="Services HTTPServices"
		paddingBottom="30" paddingLeft="30" paddingRight="30" paddingTop="30">
		<mx:Label text="Choisir le pays"/>
		<mx:ComboBox id="countryMenu" dataProvider="{ApplicationDataModel.getInstance().countryNames}"
			 change="_statesService.getStates(countryMenu.selectedLabel)"/>
		<mx:Label text="Choisir l'état"/>
		<mx:ComboBox dataProvider="{ApplicationDataModel.getInstance().statesNames}"/>
	</mx:Panel>
</mx:Application>

Dans cet exemple, une instance de StatesService est créée, et getCountries() est appelée immédiatement. La première ComboBox est data-bindée sur la propriété "countryNames" du data model. Quand l'utilisateur sélectionne une valeur dans la première ComboBox, elle appelle getStates(), en lui passant en paramètre le pays sélectionné. La seconde ComboBox est data-bindée à la propriété "statesNames" du data model.

Flex Source Code Download: Télécharger le code source complet de l'application

This movie requires Flash Player 11

Articles similaires

Commentaires (18) Trackbacks (1)
  1. Bonjour

    voici mon souci
    je veux qu' en cliquant sur ne image de la TileList le contenu de selectItem se transmette via un HTTPService à une page php qui va chercher la grande image.

    voici le code:

    MXML:
    1. <mx:Script>
    2. <![CDATA[
    3.  
    4. //chargement des images au demarrage
    5. private function creationCompleteHandler(event:Event):void {
    6.             TileListModelService.send();
    7.            
    8.             }
    9.         ]]>
    10. </mx:Script>
    11.  
    12. <!-- service à executer lorsqu'on clique sur une images de la TileListe -->
    13. <mx:HTTPService id="photoService" url="http://127.0.0.1/facestyler/services/hairStyleModel.php"
    14.          resultFormat="e4x"/>
    15.  
    16. <!-- service de chargement d'images au demarrage -->
    17.  <mx:HTTPService id="TileListModelService" url="modelList.xml" resultFormat="e4x"/>
    18.  
    19.        
    20.  <mx:TileList id="AppSelection" width="134" height="442" color="0x000000" columnWidth="116" maxColumns="1"  backgroundColor="#ffffff" borderColor="#999999"  y="30" x="10"
    21.             dataProvider="{TileListModelService.lastResult.photo}" itemRenderer="modelRenderer"  change="output.text =AppSelection.selectedItem.id"  />

    Ci-dessous le code du composant modelRenderer.mxml pour itemRenderer

    MXML:
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%"
    3.      horizontalAlign="center" verticalAlign="middle">
    4.    
    5.     <mx:Image id="img" source="{data.@url}" horizontalCenter="0" verticalCenter="0" width="100" height="100"/>
    6. </mx:HBox>

    l''affichage de la grande image ici.

    MXML:
    1. <mx:Image id="main_hairStyle" x="44.5" y="0" source="{}" scaleContent="false" height="370" width="394.5"/>

  2. Bonjour,
    pour interroger votre 2e service, vous aurez besoin d'indiquer à ce service, quelle image a été cliquée et il va vous renvoyer l'URL de l'image en grande taille correspondante (je pense que c'est ce que vous tentez de faire). Pour cela, il va falloir envoyer un paramètre à votre service. Voici un exemple:
    http://www.flex-tutorial.fr/2008/06/25/flex-httpservice-envoyer-des-parametres-avec-la-propriete-request/
    Dans votre cas, vous aurez surement quelque chose du type photoService.send({myID:AppSelection.selectedItem.id});
    Il vous suffit ensuite de traiter le résultat ou bien d'utiliser le "lastResult" comme vous l'avez déjà fait pour l'autre service.

    Fabien

  3. merci pour le coup de main
    ca marche impeccable

  4. Bonjour.
    J'utilise un HTTPService pour interroger un serveur.
    Je transmets ma requête et lorsque je réceptionne la réponse, je n'arrive pas en mode debug à voir/savoir ou se trouve l'identifiant de session normalement contenu dans le header qui se trouve être nul... (enfin si je me perd pas.)
    Quand je regarde l'objet ResultEvent, l'objet Header est null.
    Voici le code source :

    Actionscript:
    1. private function handleActionEvent(evt: Event): void {
    2.    
    3.     httpAction.removeEventListener(FaultEvent.FAULT, handleActionEvent);
    4.     httpAction.removeEventListener(ResultEvent.RESULT, handleActionEvent);
    5.    
    6.     if(evt is ResultEvent) {
    7.         fieldResponse.text = (evt as ResultEvent).result.toString();
    8.         var test : String = new String(httpAction.lastResult as String);
    9.     } else if(evt is FaultEvent) {
    10.         fieldResponse.errorString = (evt as FaultEvent).fault.faultDetail;
    11.     }
    12.    
    13.     showTitleLoading(false);
    14. }

    Auriez vous une idée ?
    Je vous remercie d'avance.

    Fred85

  5. Bonsoir, je dois importer des données xml directement dans ma base de données . Ces données seront chargé dynamiquement par l'utilisateur. Je voudrai savoir comment procéder . Merci

  6. Je viens juste de trouver le code merci

  7. Bonsoir,

    Je travaille actu sur une application ou je dois charger des thèmes de couleurs provenant de l'API kuler d'adobe. L'idée est de permettre à l'utilisateur de choisir lui même les motifs de l'application.

    Quand je teste mon appli en local ttout marche b1 mais une fois que je la lance à parti de mon serveur flash me génère une erreur : "Erreur de protection lors de l'accès à l'URL" faultCode="Channel.Security.Error" faultDetail="Destination : DefaultHTTP"

    Je ne comprends pas ce qui se passe . Aidez moi svp.

  8. Bonjour,
    Est-ce qu'il y a un crossdomain.xml à la racine de l'URL que vous essayez d'accéder? Lorsque l'on est sous Eclipse (en dev), cette protection est "désactivée" mais dans la vraie vie, il faut un crossdomain

    Fabien

  9. Aucune idée mais c'est une API de Adobe en l’occurrence kuler donc je me dis qu'ils ont du prévoir ça ?

  10. mieux je t' envoi la description du l'objet HttpService :

    kulerService.url = "http://kuler.adobe.com/kuler/API/rss/search.cfm?searchQuery="+ txt_kuler_service.text;
    kulerService.url += "&key=" + CLE_KULER;
    kulerService.url += "&itemsPerPage=3";

    kulerService.send();

    CLE_KULER est la clé qui m'a été fournie lors de mon enregistrement

  11. Leur crossdomain (http://kuler.adobe.com/kuler/API/crossdomain.xml) à l'air ok. C'est peut etre autre chose, regarde sur le net

    Fabien

  12. J'ai trouvé une librairie AS3 qui me permet d'accéder à l'API de kuler sans passer par un HttpService. Je l'ai testé et ça marche ( pour le moment ... )
    Voici le lien de la librairie http://code.google.com/p/colormunch/.
    Merci pour ton aide

    Eddoh

  13. Bonjour,
    Je travaille avec AIR.
    Au chargement d'un formulaire, je dois récupérer un certain nombre d'informations issues de ma base mySQL.
    Pour se faire j'ai donc créé différents httpservice en procédant à des regroupements logiques, enfin je pense.
    Un httpservice par combobox et un par datagrid.
    Mon probléme est que lorsque mon formulaire s'affiche l'on voit les différentes informations se charger. Ma question est comment afficher le formulaire une fois que tous les httpservices ont renvoyé leurs résultats. Merci par avance.

  14. Bonjour,
    Plusieurs solutions.
    1/ La plus simple. Ta ComboBox est bindée à un dataProvider que tu as défini à l'extérieur

    Il te suffit d'ajouter:

    2/ La moins simple. Tu récupères le résultat de ton HTTPService dans par l'évènement result. Dans le code de l'écouteur d'évènement, tu rends ta ComboBox visible

    Fabien

  15. Merci pour cette réponse rapide.
    J'ai bien bindé ma combobox et l'ensemble de mes champs comme il faut.
    Mais je souhaiterai savoir s'il n'est pas possible de rendre ma window enable par exemple tant que je n'ai pas récupéré tous les résultats des httpservice.

  16. Ah désolé les tags ne sont pas passés dans mon commentaire !
    donc tu as:
    mx:ComboBox dataProvider="{monDP}" enabled="{monDP.length > 0}"

    Quelque chose comme cela :)

    Fab

  17. Super idée.
    Merci beaucoup


Leave a comment

(required)