9 janvier 2009
Imprimer ce billet

Les évènements dans des composants Flex réutilisables

Dans un précédent article, nous vous présentions comment créer des composants Flex réutilisables. Nous allons ici poursuivre la présentation en vous parlant de la gestion des évènements au sein de ces composants. En effet, il n'est pas évident de gérer les évènements lorsque ceux-ci sont dans des fichiers MXML différents. Alors comment faire ?

Une solution existe, utiliser les tags Metadata et plus précisemment le tag Event. Dans l'exemple du billet précédent, nous avons créé plusieurs composants pour mettre en place un formulaire. Nous allons effectuer le même exercice, avec une liste de contacts dans laquelle il est possible d'ajouter des utilisateurs. Nous verrons comment deux composants indépendants l'un de l'autre pourront communiquer et échanger des données.

Ce billet se découpe de la façon suivante :

Mise en place des composants réutilisables

Pour créer notre application, nous allons mettre en place :

  • ContactListView : une liste de contacts contenant une Datagrid et un bouton Ajouter
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
    width="400" height="300"
    horizontalAlign="center">

    <mx: DataGrid width="100%" height="100%" dataProvider="{contacts}">
        <mx:columns>
            <mx: DataGridColumn headerText="Nom et prénoms"/>
        </mx:columns>
    </mx: DataGrid>
    <mx:Button label="Ajouter"/>

</mx:VBox>

  • ContactFormView : un formulaire contenant un champ texte nom, un autre prénom et deux boutons Valider et Annuler
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300">
    <mx:Form width="100%" height="100%">
        <mx:FormItem label="Nom" width="100%">
            <mx:TextInput width="100%" id="lastName"/>
        </mx:FormItem>
        <mx:FormItem label="Prénom" width="100%">
            <mx:TextInput width="100%" id="firstName"/>
        </mx:FormItem>
        <mx:FormItem width="100%">
            <mx:HBox width="100%" horizontalAlign="right">
                <mx:Button label="Valider"/>
                <mx:Button label="Annuler"/>
            </mx:HBox>
        </mx:FormItem>
    </mx:Form>
</mx:VBox>

Ils seront stockés dans une pile de vues ({{ViewStack}}). Le composant ViewStack contient des vues filles dans lesquelles il est possible de naviguer. Seule une vue fille peut être affichée à la fois grâce à la propriété selectedItem ou selectedIndex. En manipulant ce composant, nous allons tenter de passer d'une vue à l'autre en modifiant la valeur de selectedIndex.
- selectedIndex = 0 : le ViewStack affiche ContactListView
- selectedIndex = 1 : le ViewStack affiche ContactFormView

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:ViewStack id="viewStack">
        <view:ContactListView id="contactListView"/>
        <view:ContactFormView id="contactFormView"/>
    </mx:ViewStack>
</mx:Application>

Lorsque l'utilisateur clique sur le bouton Ajouter, l'application change de vue pour passer sur le formulaire. Les boutons Valider et Annuler quant à eux permettent de revenir sur la première vue.

La partie graphique est en place mais comment signaler à la pile de vue de passer de l'une à l'autre ? Effectivement depuis une vue, comment peut-on signaler à son parent qu'il s'est passé quelque chose ?

C'est là que les tags Metadata viennent à notre secours.

Qu'est ce qu'un tag Metadata ?

Un tag Metadata fournit au compilateur des informations sur la façon dont le composant MXML est utilisé dans une application Flex. Il existe 12 tags Metadata documentés dont entre autres Bindable, Embed, Effect et celui que nous allons utilisé Event. Le tag Event permet de définir des évènements que le composant concerné peut déclencher, ce qui convient très bien à notre problème.

Et concrètement ?

Côté déclencheur

Créons un tag Event dans notre vue ContactListView:

<mx:Metadata>
    [Event(name="addContact", type="flash.events.Event")]
</mx:Metadata>

Lorsque l'utilisateur clique sur le bouton Ajouter, le composant déclenche l'évènement addContact.

<mx:Script>
    <![CDATA[

        import mx.collections.ArrayCollection;

    [Bindable]
    private var contacts:ArrayCollection;

        private function onClick():void{
            // on dispatche un nouvel évènement
            // qui sera intercepté ici par le composant parent
            dispatchEvent(new Event("addContact"));
        }

    ]]>
</mx:Script>

<mx: DataGrid width="100%" height="100%" dataProvider="{contacts}">
    <mx:columns>
        <mx: DataGridColumn headerText="Nom et prénoms"/>
    </mx:columns>
</mx: DataGrid>
<mx:Button label="Ajouter" click="onClick()"/>

Côté abonné

Le parent de la vue, qui est ici l'application, ajoute un listener sur la vue pour attendre l'évènement addContact. Une fois l'évènement déclenché, nous changeons de vue.

<mx:Script>
    <![CDATA[
        import mx.collections.ArrayCollection;

        private function onAddContact(event:Event):void{
            // passage de la vue contenant la liste de contacts
            // à la vue d'ajout de contacts.
            viewStack.selectedIndex = 1;
        }
        ]]>
</mx:Script>

<mx:ViewStack id="viewStack">
    <view:ContactListView id="contactListView" addContact="onAddContact(event)"/>
    <view:ContactFormView id="contactFormView"/>
</mx:ViewStack>

Résultat

En faisant de même avec les boutons Valider et Annuler, nous arrivons au résultat suivant:


Ce billet présente un exemple très simple d'utilisation du tag Event avec un évènement de type flash.events.Event. Mais vous pouvez créer vos propres classes d'évènements comme le montre le livedocs. Le code source est disponible ici, vous trouverez l'exemple complet avec la gestion de l'ajout d'un contact et le retour vers la liste.

Références

http://livedocs.adobe.com/flex/3/html/help.html?content=metadata_2.html

Mots-clefs :,