Rss Feed

Enlever le focus d’un élément

Il existe bien une fonction pour mettre le focus sur un élément. Par exemple sur un textinput qui s’appelle tiName, il suffit de faire un tiName.setFocus() pour voir apparaitre automatiquement le focus. Malheureusement, il n’existe pas de fonction tiName.unsetFocus(), ou tiName.removeFocus().

La solution est finalement assez simple, puisqu’il suffit de faire un Stage.focus = null;

En fait, la fonction setFocus() ne fait pas grand chose d’autre qu’un Stage.focus = tiName; donc il est possible de récupérer depuis n’importe où l’élément sur lequel est le focus.

Petite astuce pour enlever le focus d’un élément d’un datagrid (nommé dg), il suffit de faire dg.selectedItem = null;

Upload d’un fichier vers PHP

Vous utilisez flex et voulez envoyer un fichier en utilisant un script PHP. Donc direction la documentation de flex, et on trouve des exemples de code. Après avoir épuré le code car les prints ou echo dans le vent, on ne voit pas trop l’intérêt, on test un upload. Et là, la fonction indiquant qu’on a fini l’upload (
fileRef.addEventListener(Event.COMPLETE, completeHandler);) n’est pas appelée…

Après pas mal de recherche, on se rend compte qu’en fait, il faut laisser au moins un echo, pour que flex se rende compte que le script a bien été appelé… que de temps perdu pour une chose si simple.

Observer les changements d’une variable

Vous souhaitez effectuer une action dès lors qu’une variable est modifiée ? Rien de plus simple grâce à la classe « ChangeWatcher« , littéralement « Surveillant de changement », et particulièrement grâce à la méthode statique watch().

Les paramètres minimum à lui passer sont les suivants :

host -> l’objet qui contient la variable. Si vous êtes dans un mxml, l’objet sera « this »,

chain -> la variable ou la chaine de variable que vous souhaitez surveiller,

handler -> la fonction à appeler en cas de changement.

Il est de bon ton de tester avant si la variable est surveillable, à l’aide de la fonction statique canWatch() qui reprend les mêmes paramètres que la fonction watch() à l’exception de l’handler. Elle retourne un bool, et en cas d’une réponse positive, on peut lancer la surveillance.

Voici donc une méthode rapide et efficace de bind.

Pour vos projets Flex : coding conventions and best practices

Pour les développeurs ActionScript 3 qui souhaitent écrire du code respectueux des standards, avoir des projets Flex qui tiennent la route et qui puissent être repris par d’autres développeurs Flex, voici une page à bookmarker ;)

Flex Coding Conventions and best practices

SOAP+Flex => SchemaTypeRegistry

Une nouveauté de Flex 3 qui est passé inaperçue c’est la possibilité de recevoir des objets fortement typés depuis un service SOAP comme on pourrait le faire via le protocole AMF. Tout se fait dans la class singleton SchemaTypeRegistry. Il suffit de lui fournir le nom de l’objet reçu , son namespace dans l’enveloppe SOAP et la class de destination. Un petit exemple vaut mieux qu’un long discours : Imaginons que l’on veuille maper un objet user ayant pour namespace « http://www.matsiya.fr/user » vers une class User il suffira d’ajouter dans l’application (le mapping concernera alors tous les services) :

SchemaTypeRegistry.getInstance().registerClass(new QName("http://www.matsiya.fr/user", "user"), User);

Il est aussi tout à fait possible de définir le SchemaTypeRegistry pour une opération donnée en le spécifiant au XMLDecoder :

var sr:SchemaTypeRegistry = new SchemaTypeRegistry(); sr.registerClass(new QName("http://www.mastiya.fr/user", "user"), User);op.decoder.typeRegistry = sr; //op étant notre opérationEtrange qu’adobe ne communique pas plus à ce sujet, la doc est quasi inexistante pour cette fonctionnalité et surtout tout ce qui touche au XMLDecoder. Malheureusement cette technique n’est utilisable que pour les services de type SOAP, à ma connaissance il n’est pas possible de forcer le décodage d’un XML externe ou résultant d’un service REST via le XMLDecoder.

Retour sur le Adobe onAir Tour

Et oui, comme annoncé ici, nous nous sommes rendu au Adobe onAir Tour qui se déroulait au palais Brongniart à Paris. On arriva donc sur les coups de 09h45, on récupère nos badges, notre petite pochette de bienvenue (contenant autocollants, carte postale au couleur d’AIR, et un petit fascicule), et un tee-shirt aux couleurs du onAir tour, nous nous dirigeons vers le hall principal où se trouvent tout ce qu’il faut pour casser le croute. Au menu, viennoiseries miniatures, boissons froides et chaudes, fruits, et le tout à volonté. Le cadre du palais est très agréable, on se dit qu’Adobe se donne les moyens de son ambition :)

Puis on se dirige vers le lieu où tout va se passer, et là on découvre l’amphithéâtre qui est très classe, disposant du wifi, et de prises pratiquement à chaque siège pour brancher nos compagnons favoris. Sur scène, le maitre de cérémonie, alias Mike Chambers, est en train de régler les dernières choses, aidant Ryan Stewart à se préparer pour sa keynote.

10h, Mike nous remercie d’être venu, et nous indique le programme de la journée, et laisse la parole à Ryan qui va nous présenter Adobe, le chemin parcouru (je ne savais pas que flash avant 13 ans :o ), mais aussi ce qu’est AIR. On y découvre (ou redécouvre) les produis phares d’Adobe, mais aussi certains moins connus tels que Scene7, ou Pacifica. On apprend aussi que Aptana (un IDE Ajax/Php/Html) contient désormais un plugin AIR, ainsi que la version 1.1 de AIR serait disponible courant 2008, qui contiendra pas mal de correctifs de bugs, mais aussi l’ajour du support multi-langage (l’installation des applis AIR est toujours en anglais).

10h30, Mike nous présente comment construire sa première application AIR avec Flex Builder.

11h, Kevin Hoyt vient quand à lui nous parler de la création d’un appli AIR avec de l’Html et du Javascript. N’ayant pas vraiment abordé cet aspect jusqu’à présent, je suis très heureux d’avoir pu découvrir la simplicité déconcertante de migration d’une appli html/javascript (et donc ajax) vers du AIR.

11h30, on se fait un petit break, histoire de nous remettre de nos émotions (et à l’occasion, nous ravitailler l’estomac ;) )

11h50, Kevin revient nous parler plus en profondeur des possibilités d’html/javascript au sein d’un application AIR.

12h30, c’est la pause déjeuner, au menu, mini sandwichs, parts de quiche, mini hamburger (ils étaient divins), chips, fromage, et des verrines de fruit. Et le tout toujours à volonté. Franchement, c’était royal :D

13h15, on reprend avec Serge Jespers qui nous parle de comment déployer et mettre à jour un application AIR. On y apprend comment déployer notre application AIR sur une page web en utilisant les « badge ». Très pratique, et visuellement intéressant, vous pouvez trouver plus d’infos sur les nouveaux badges sur le labs.

13h45, Daniel Dura vient nous faire un tour d’horizon de l’API AIR.

14h20, De nouveau une pause pour prendre un petit café pour éviter que la digestion nous emporte vers un sommeil profond (non pas que ça ne soit pas intéressant, mais le répas ayant été tellement bon, difficile de résister aux bras de morphée).

14h40, Chris Brichford vient nous parler à son tour d’application AIR utilisant HTML et javascript, en abordant particulièrement les aspects de sécurité, et ce que l’API Air peut faire avec de l’html.

15h15, Enrique Duvos nous a présenté une session très intéressante sur tout ce qui est optimisation, charge des applications AIR pour des développements qui ne sont plus que des cas d’école. Très vivante, et pleine d’exemple, je pense que c’était la meilleure session de cette journée.

15h45, Et hop, une autre pose pour se ravitailler.

16h00, Christophe Jolif nous expose en français (et oui, c’était un compatriote pour une fois ;) ) comment au sein d’ILOG, ils utilisent AIR pour faire de la visualisation de statistiques. Au menu, des charts, des charts, des datagrids et autres charts ;)

16h35, Andre Charland de Nitobi nous présente ce que sa société fait avec AIR, en particulier avec l’utilisation des frameworks Ajax.

17h10, Lee Brimelow prend la suite. Avec une session nommée AIR Conditioning (allusion pas du tout dissimulée à nos bonnes vieilles clims), il nous présente ses habituelles applications déjantée pour nous montrer les possibilités de AIR utilisant Flash ou Flex. On voit donc un player vidéo avec des formes farfelues, un autre player qui fait des captures d’écran très sympa.

Nous avons du partir avant la fin de la session de Lee, étant donné qu’il y avait eu du retard accumulé sur la journée, et pour être sur de ne pas rater le train ;)

Cette journée a permis donc de revoir ces stars d’Adobe, de découvrir des aspects de AIR qui ne sont pas toujours mis en avant, mais on se dit quand même qu’Adobe cherche à convaincre tous les développeurs Ajax/Javascript de les rejoindre. Ce qui fait que cette journée, pour des développeurs Flex que nous sommes, n’était pas complétement à la hauteur de nos espérances. On aurait aimé aussi avoir quelques exclusivités sur l’avenir des produits Adobe qui touchent AIR/Flex/Flash, mais ça ne semblait pas être leur intention.

Reste qu’on ne regrette pas cette journée ;)

Pseudo comportement synchrone en flex

Si vous programmez depuis quelques temps en AS3, vous avez du vous rendre compte que les événements sont asynchrones, c’est à dire que l’on ne va pas avoir le résultat d’une fonction dès l’exécution de cette dernière terminée, mais au bout d’un temps indéterminé, et uniquement via une fonction qui collecte l’événement en question.

Hors il est parfois nécessaire d’avoir un certain ordonnancement dans les actions, en particulier lorsque l’on utilise des web services ou autre remoting.

Imaginons que l’on veut récupérer une liste de clients une fois que l’on a récupéré la liste des catégories de clients disponibles. Il existe 2 méthodes pour résoudre ce problème :

  1. Il suffit d’appeler la méthode de récupération des clients dans l’ »handler » de la fonction de récupération des catégories de clients.
  2. On utilise la méthode callLater(function, args);

Voici des exemples de codes mettant en place les 2 méthodes. (On assume ici que notre webservicesObject a un eventListener sur la méthode getCategoriesClients et un sur la méthode getClients() qui emmène respectivement sur categoriesClients_handler et clients_handler)

1ère méthode :

private function init():void {
webservicesObject.getCategoriesClients();
}

private function categoriesClients_handler(e:Event):void {
trace("Récupération des catégories de clients terminée");
webservicesObject.getClients();
}

private function clients_handler(e:Event):void {
trace("Récupération des clients terminée");
}

2ème méthode :

private var isCategoriesLoaded:Boolean : false;


private function init():void {
webservicesObject.getCategoriesClients();
webservicesObject.getClients();
}

private function categoriesClients_handler(e:Event):void {
trace("Récupération des catégories de clients terminée");
isCategoriesLoaded = true;
}

private function clients_handler(e:Event):void {
if(isCategoriesLoaded)
trace("Récupération des clients terminée");
else
callLater(clients_handler, e);
}

La fonction callLater(function, args) va donc rappeler notre handler en repassant en paramètre l’événement, de la même manière qu’a été déclenché l’événement par le webservice.

Empécher la mise à jour d’un ArrayCollection

Il vous est déjà arrivé de vous prendre la tête car vous ne vouliez pas voir votre repeater « clignoter » dès que vous modifiez une valeur de l’ArrayCollection qui lui sert de DataProvider. Cela arrive généralement quand vous devez modifier plusieurs objets, ou éléments d’un objet contenu dans l’ArrayCollection, le repeater se met à jour, et donc recréé tous ses éléments à chaque évènement CollectionEvent déclenché par l’ArrayCollection. Pour peut que vous ayez des appels de fonction pour générer des labels, ou pour traiter les éléments à afficher, ça peut donner cet effet de clignottement assez pénible, ainsi qu’une augmentation des ressources de la machine du client.

Il existe un moyen très rapide de bloquer le déclenchement des évènements. La fonction disableAutoUpdate() est faite pour vous. Une fois que vous avez fait toutes vos modifications, il suffit de réactiver le déclenchement de ces évènements avec la fonction enableAutoUpdate(), et tout rentrera dans l’ordre.