Archives du mot-clé namespace

Flex 4 (6) – Composants graphiques qui n’apparaissent plus après une migration depuis Flex 3 [Résolu]

J’ai eu aujourd’hui, un commentaire sur la page de la ToasterLib, me demandant s’il y avait une version Flex 4 de cette librairie. Je me suis donc attelé à la tâche cette après-midi. Même si mon apprentissage de Flex 4 est loin d’être au point, la ToasterLib n’a que peu de dépendances vers Flex (Canvas, Label tout au plus), je pensais donc que cela allait être aisé.

Mais je commence à comprendre pourquoi Adobe conseille de ne pas faire de migrations « bêtes et méchantes » Flex 3 vers Flex 4. Il faut en effet être méticuleux dans le remplacement des composants, connaître leurs équivalences et les petites modifications de comportement.

Migration de la ToasterLib

Pour créer une version utilisable avec Flex 4 de la ToasterLib, j’ai pris mon projet Flex 3 sous Flex Builder 3, j’ai crée une branche SVN nommée « ToasterLibFx4″ et j’ai fait un checkout de ce projet dans Flash Builder 4. A l’import, je précise bien que je veux utiliser le SDK Flex 4.0 me voilà opérationnel.

Je commence donc à modifier les Canvas en SkinnableContainer, à mettre les paddings/horizontalCenter/verticalCenter sur les propriétés « layout » des composants (on verra cette partie plus tard dans les tutoriaux Flex 4). Après ces quelques modifications, mon projet d’exemples compile et fonctionne presque correctement en seulement 30 minutes! « Presque » correctement car déjà un premier problème se présente…

L’effet Move d’entrée est joué mais le composant n’est pas visible avant la fin de l’effet

Le premier effet qui est appliqué aux Toast est un effet d’arrivée crée par un Move appliqué au Toast. Petite surprise, celui-ci semble ne pas se produire et on voit seulement le Toast à la fin de la durée de l’effet (500ms). Avant ce délai, le composant n’est même pas visible. Les effets suivants (Blur, Fade) et même le Move qui se produit à la disparition du Toast sont par contre joués comme ils le devraient.

Première piste, vérifier que l’effet est bien joué pendant une durée correcte:

...
var moveEffect:Effect = _effectDescriptor.getMoveToStackTopEffect(toastMessage, moveFromPoint, moveToPoint);
moveEffect.addEventListener(EffectEvent.EFFECT_START, function onEffectStart(event:EffectEvent):void{trace ("start: " + getTimer());});
moveEffect.addEventListener(EffectEvent.EFFECT_END,function onEffectStart(event:EffectEvent):void{trace ("end: " + getTimer());});
moveEffect.play()
...
start: 3103
end: 3599

Pas de problème à ce niveau là, le Move est bien lancé quand on fait play(). Il faut donc chercher une autre piste.

Deuxième piste, vérifier que l’on ne lance pas l’effet trop tôt (de-sychronisation):

...
var moveEffect:Effect = _effectDescriptor.getMoveToStackTopEffect(toastMessage, moveFromPoint, moveToPoint);
setTimeout(moveEffect.play, 1000);
...

On décale ici la lecture de l’effet d’une seconde. A l’écran, on voit alors que le Toast apparait en (0,0) puis l’effet se joue, ce qui fait que le Toast « sursaute ». Seulement, s’il on réduit le délai à 100ms, le composant ne s’affiche plus, comme avant. Avec l’habitude d’utiliser Flex, on acquiert un petit doigt spécial qui nous dit que le composant a besoin d’être entièrement crée (évènement FlexEvent.CREATION_COMPLETE) pour que l’effet puisse se jouer.

Voici donc le troisième test:

// TODO
// find a way to trigger the effect onCreationComplete without using an anonymous function
// that will prevent the toastmessage from being collected
toastMessage.addEventListener(FlexEvent.CREATION_COMPLETE, function onToastMessageCreationComplete(e:Event):void{moveEffect.play()});

Ici, on s’inscrit sur l’évènement CREATION_COMPLETE du toast. Quand celui-ci se produit, on lance l’effet. J’ai choisi ici de passer par une fonction anonyme qui me permet de garder directement la variable « moveEffect » dans le « scope » de la fonction. En effet, avec une méthode de handler classique, je n’aurai plus eu accès à la variable « moveEffect ».

Attention, comme précisé dans le commentaire, ce n’est pas une bonne pratique car cela signifie que même fermés, les Toasts seront mal ou pas du tout détruits par le Garbage Collector. Dans le futur, il faudra trouver une meilleure solution ;)

Presque sans surprise, cette solution fonctionne. Je ne sais pas pourquoi mais avec Flex 3, je n’avais pas besoin de faire cette manipulation. Peut-être est-ce un bug, je ne sais pas vraiment.

En passant d’une Box à un BorderContainer, les composants enfants ne s’affichent plus

Pour être plus cohérent avec Flex 4, je décide de « migrer » la classe ToastMessageBase. La classe ToastMessageBase est comme son nom l’indique, la classe dont on va hériter pour créer un « Toast ». Cette classe, avec Flex 3, héritait de Box. Puisque j’ai besoin d’un « Canvas avec border », je choisis de remplacer Box par BorderContainer qui va me donner le même fonctionnel.

Lire la suite

Flex 4 – Différences entre Flex 3 et Flex 4 (2-Nouvelle architecture Flex 4)

Traduction de l’article Differences between Flex 3 and Flex 4 beta de Joan Lafferty.

Un des principaux aspects de Flex 4 et le workflow entre designers et développeurs. Pour cela, le framework apporte une séparation claire entre le visuel et le comportement d’un composant. Dans Flex 3, le code d’un composant comprenait son comportement, sa mise en page et ses changements visuels. Dans Flex 4, les composants sont séparés en différentes classes, chacune traitant d’un comportement spécifique.

Une nouvelle architecture autour du FXG

Comme spécifié dans le document officiel Gumbo Architecture Document:

La classe principale du composants, celle dont le nom correspond au tag MXML du composant, encapsule le comportement principal du composant. Cela comprend la définition des évènements propagés par le composant, la donnée que le composant représente, la liaison avec des sous-composants, la gestion et le suivi de l’état interne du composant.

On couple avec cette classe de composant, une classe de skin qui gère tout ce qui est lié à l’apparence visuelle du composant dont les éléments graphiques, la mise en page, la représentation de la data, le changement d’apparence entre les différents States et les transitions entre ces State. Dans le modèle Halo, les skins Flex étaient des éléments graphiques responsable seulement de l’aspect graphique du composant. Changer n’importe quel autre aspect de l’apparence d’un composant, comme la mise en page ou la visualisation des states obligeait à créer une sous-classe du composant et à éditer le code ActionScript directement. Dans le modèle Gumbo, tout cela est définit déclarativement dans une classe de skin, principalement à l’aide des tags graphiques FXG.

Voir les spécifications du format FXG 1.0

Pour illustrer cette nouvelle architecture, on va regarder le code de la classe spark.components.Button. Cette classe ne contient que la logique du comportement du bouton. Tous ce qui concerne le visuel du composant est défini dans la classe spark.skins.default.ButtonSkin.

Pour des raisons de performance, Flex 4 donne aux développeurs des briques qu’ils peuvent utiliser pour construire la fonctionnalité dont ils ont besoin. Des fonctionnalités lourdes telles que le scroll ou la virtualisation qui ne sont pas nécessaires à toutes les applications ne sont pas appliquées par défaut.

Namespaces et packages dans Flex 4

Les classes de Flex 4 sont dans les mêmes packages mx.*. Flex 4 introduit le package spark.* pour les composants et les classes de base, effects, filters, layouts, primitives, skins et utils.

Flex 4 apporte un nouvel ensemble de composants et d’effets ayant le même nom que ceux de Flex 3. Pour éviter les conflits MXML, Flex 4 comprend 4 namespaces différents: MXML 2006, MXML 2009, Spark et Halo.
Lire la suite

Flex 4 – Nouvelle architecture, la fin du préfixe Fx et le nouveau namespace fx:

Si vous suivez un peu ce qui se passe sur la blogosphère Adobe et notamment sur les blogs des evangelists de la team Flex SDK, vous avez sûrement entendu parler du préfixe Fx. En effet, pour la sortie du SDK Flex 4 (alias Gumbo), l’architecture du SDK change pour devenir plus modulaire et de nouvelles classes font leur apparition. Parmi ces nouvelles classes, les nouveaux composants (les « Gumbonents ») posent plusieurs problèmes:

  • Flex 4 doit pouvoir compiler des projets Flex 3. Cela veut dire qu’ils ne peuvent pas renommer les classes existantes.
  • Puisque l’on ne peut pas renommer les classes existantes, comment nommer les package pour qu’ils aient un sens

En effet, l’équipe du SDK ne peut pas appeler le nouveau Button, « Button » pour des raisons évidentes de conflits de nommage. La première proposition a été de nommer cette classe FxButton (et c’est la même chose pour FxCheckBox, FxTextInput, etc.). Cela permettait d’utiliser à la fois un <mx:Button> et un <FxButton> dans une application pour avoir les deux composants des deux SDK.

Cette proposition était fonctionnelle mais a largement été rejetée par la communauté Flex pour plusieurs raisons:

  •  Il deviendrait plus difficile pour un débutant d’apprendre les bases de Flex (par exemple, tag MXML <=> Nom de la classe ActionScript). Flex deviendrait donc plus difficile d’accès
  • Quid des prochaines versions de Flex, encore un nouveau préfixe ?

Matt Chotin a annoncé il y a peu de temps sur les forums Adobe, l’abandon du préfixe Fx en faveur d’un nouveau namespace (fx:). Il faut noter que c’est une proposition lancée par la communauté Adobe Flex, et c’est la que l’on se rend compte de l’aspect Open Source du projet. Ainsi, vous pourrez créer un Gumbonent Button en faisant <fx:Button>, tout en gardant la possibilité de faire un <mx:Button>. Tout se joue dans le namespace (le préfixe) qui va déterminer le chemin du package

Pour le MXML, il y aura donc 3 namespace pour Flex 4:

  • le namespace MXML 2009 (http://ns.adobe.com/mxml/2009)
  • le namespace Halo ( library://ns.adobe.com/flex/halo)
  • le namespace Spark (library://ns.adobe.com/flex/spark)

Il y aura aussi une nouvelle structure de packages, avec notamment les packages Spark.

Il faudra aussi que des modifications soient faites pour que les CSS supportent les namespace et que Flex Builder puisse les supporter. En effet, avec les « Type Selector », si on donne Button{}, comment Flex saura-t-il sur quel Button appliquer le style :)

Pour en savoir plus sur cette réorganisation, voici la page officielle sur le projet Gumbo:

Flex 4 Gumbo: Dropping the Fx Prefix

Flex ActionScript – Récupérer des éléments / attributs XML avec e4x avec n’importe quel namespace

Parser un xml avec e4x est vraiment simple. Il y a quelques jours, j’avais publié un article sur comment lire des attributs XML ayant un Namespace différent avec e4x. Mais dans certains cas, vous ne saurez pas forcement quels namespace vont être présents. Prenons comme exemple ce XML :

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <rdf:Description>
        <rdf:value>xxx</rdf:value>
    </rdf:Description>
</rdf:RDF>

Ici on peut voir que le namespace rdf (préfixe rdf) est défini par http://www.w3.org/1999/02/22-rdf-syntax-ns#. Pour accéder au nœud rdf:value, vous pouvez donc faire:

var rdf:Namespace = new Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
var attributes:XMLList = XML(event.result).rdf::Description.rdf::value;

Cette technique fonctionne car vous connaissez à l’avance le namespace qui sera utilisé. Mais vous pouvez utiliser un joker (*) pour que cela fonctionne dans n’importe quel cas:

var attributes:XMLList = XML(event.result).*::Description.*::value;

Flex ActionScript – Lire des attributs XML ayant un Namespace différent avec e4x

Dans la plupart des cas, e4x facilite grandement la lecture et l’écriture d’un fichier XML en ActionScript. La syntaxe pointée permet de récupérer facilement des éléments tandis que l’opérateur .@ permet de récupérer les attributs des noeuds XML.

Je voulais parser ce XML provenant d’un service WMS (Version réduite):

<Get>
  <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.bsc-eoc.org/cgi-bin/bsc_ows.asp?"/>
</Get>

Pour mon application Flex,  il fallait que je récupère la valeur de l’attribut href: http://www.bsc-eoc.org/cgi-bin/bsc_ows.asp?. Donc de manière assez habituelle, j’ai essayé:

xml.OnlineResource.@xlink:href

Mais comme le « : » est interprété par le compilateur, je me prend l’erreur de syntaxe:

1084: Erreur de syntaxe : rightparen est attendu devant colon.

Donc j’essaie ensuite avec la notation tableau:

xml.OnlineResource.@["xlink:href"]

Je trace ma valeur, rien ne s’affiche, aucune valeur d’attribut XML n’est donc récupérée. En regardant un peu sur la doc d’XML en ActionScript 3, je me rend compte qu’il faut en fait manipuler ce namespace « xlink ».

Lire la suite