Et si l'avenir des IHMs (Web) était à la mixité?
Lorsqu'on regarde une application "grand public", on note au moins les besoins suivants : rien de génial la dedans, interagir avec des données, de consulter et de naviguer dans du contenu mise en forme. A côté de ces besoins, on recherche souvent "THE" solution, celle qui va résoudre tous nos problèmes, celle qui va répondre à tous nos besoins. Reste que si une telle technologie existait, on l'aurait déjà trouvée. Un peu comme les alchimistes qui recherche à transformer le plomb en or...
J'ai cette impression que ces applications devront - au moins à moyen terme - mixer les technologies. Flex est adapté pour réaliser des interactions utilisateurs trés riches, trés visuelles : slider, drag&drop, transitions visuelles et autres effets visuels... . A l'inverse, HTML reste la technologie la plus adaptée pour gérer du contenu mis en forme, pour assurer la navigabilité dans ce contenu. Dès lors, comment faire communiquer ces deux mondes : Flex et HTML.
Adobe répond à cette question et propose l'ExternalInterface. Cette classe permet d'exécuter des méthodes JavaScript depuis Flex ou des méthodes Flex depuis JavaScript et bien entendu de passer des arguments; des données d'un monde à l'autre.
Communiquer entre les deux mondes...
Pour interagir avec JavaScript et HTML depuis une application Flex, l'objet ExternalInterface
propose une méthode call()
qui permet de préciser le nom de la méhtode JavaScript a appeler ainsi que les paramètres qui seront transmis. Au niveau HTML, on définit cette fameuse méthode JavaScript point d'entrée dans le monde HTML
<script>
function setSelectedItem(obj)
{
//do what you wanna do
}
</script>
Au niveau du code Flex
<mx :Application....
<mx:Script>
< ![CDATA[ import mx.controls.Alert; private function clickHandle(e:Event) : void { //appel de méthode JS if (ExternalInterface.available) { ExternalInterface.call("setSelectedItem", selItem.text); } } <mx:VBox> <mx :TextInput id="selItem"/> <mx :Button click="clickHandle(event)"/> </mx> ``` La méthode `setSelectedItem` définie dans le JavaScript sera exécutée sur l'évènement "click" depuis l'application Flex... Passer du monde JavaScript au monde Flex n'est guère plus complexe. Au niveau du code HTML tout d'abord où l'on note :- le passage de paramètres à la méthode Flex - une subtilité liée au navigateur : les applications Flash ne sont pas référencées de la même manière suivant que l'on utilise Internet Explorer ou des navigateurs de type Mozilla ``` function getMyApp(appName) { if (navigator.appName.indexOf ("Microsoft") !=-1) { return window[appName]; } else { return document[appName]; } } function callFlexMethod() { var param = "blabla; var param2 = 12; getMyApp("myApp").myFlexFunction(param, param2); } <div id="fromJS"> <button onclick="callFlexMethod();">click !!</button> </div> ``` Au niveau du code Flex enfin, on note l'utilisation de la méthode `addCallback()`. Cette méthode permet d'enregistrer les méthodes exposées par l'application Flex et donc accessible depuis le JS de la page HTML. ``` <mx :Application ... creationComplete="initApp()"> </mx><mx :Script> public function initApp():void { ExternalInterface.addCallback("myFlexFunction",myFunc); } public function myFunc(s:String, i:uint):void { try { if(i>0) selItem.text = s; ... } catch (e:Error) { //gestion des erreurs } } ]]> </mx> <mx :VBox> <mx :TextInput id="selItem"/> ... </mx> ``` ## Et le [Flex Ajax Bridge](help.html?content=ajaxbridge_1.html)?
Un des [inconvénients](http://livedocs.adobe.com/flex/3/html/help.html?content=ajaxbridge_1.html) que l'on peut voir à `l'ExternalInterface` reste le caractère manuel de la tâche. Manuelle sur au moins deux points :- la définition des méthodes qu'il est possible d'appeler
- le "boiler plate code" qu'il est nécessaire de mettre en oeuvre pour établir le dialogue
Alors Adobe propose un [bridge](http://livedocs.adobe.com/flex/3/html/help.html?content=ajaxbridge_1.html) (concrètement un fichier js qu'il est possible de générer depuis Flex Builder) permettant de plus facilement faire interagir les deux mondes. Imaginez le composant graphique suivant dans votre application Flex:
<fab :FABridge xmlns:fab="bridge.*" /> ... <mx :TextInput id="selItem"/> ...
En fait, ce bridge permet de manipuler des objets ActionScript depuis le monde JavaScript, sans aucun ajout de code. Bref, d'utiliser l'ensemble des APIs fournies par ActionScript depuis JavaScript.
... <script> function doIt() { var flexApp = FABridge.flash.root(); var flexObj = flexApp.getSelItem(); ... alert(value.getTextWidth() + ' ' + value.getText()); } </script> ...
_**Remarque** : les méthodes `getTextWidth()` et `getText()` sont "celles" définies sur l'API ActionScript de TextInput_
Faire communiquer le monde HTML/Javascript et le monde Flex est donc plutôt simple. L'ExternalInterface propose certes une solution assez manuelle mais présente peut-être l'avantage de bien définir les "ponts" entre les deux mondes. A contrario, le "Flex Ajax Bridge" permet à JavaScript d'accéder à l'ensemble des [APIs ActionScript](http://www.bobbyvandersluis.com/swfobject/flex3/flex_updated/FABridge/index.html). Un bridge trés ouvert qui enrichi drastiquement JavaScript mais qui couple fortement les deux mondes, les deux IHMs.