Flex Item Renderer – Communiquer avec un itemRenderer grâce à des Event
Toujours la suite de l'article de Peter Ent sur la communication entre les itemRenderer et votre application. Cette fois-ci, une nouvelle approche, plus modulaire qui est la manipulation d'évènements. Dans les exemples précédents, on a utilisé une TileList qui présente des produits. Chaque produit étant représenté par un itemRenderer avec une image, du texte et un bouton. Ce bouton sert en théorie à acheter le livre en question. Seulement, le <mx:Button> est dans l'itemRenderer et la phase d'achat se fera vraisemblablement dans votre application principale (pas dans l'itemRenderer en tout cas). Il faut donc faire remonter (bubble up) l'évènement du clic bouton vers l'application.
Quand l'utilisateur clique sur un bouton pour acheter un livre, c'est le composant liste qui est responsable de communiquer cette information à l'application. Ce qui nous donne donc quelque chose comme:
<CatalogList buyBook="addToCart(event)" />
Voici donc le code à utiliser pour dispatcher cet évènement de manière propre par le composant Liste. Tous les composants (CatalogList) sont issus de l'exemple précédent.
- Ajouter tout d'abord un tag metadata au composant CatalogList pour indiquer au compilateur que le composant va dispatcher l'évènement
import events.BuyBookEvent;
import mx.controls.TileList;
[Event(name="buyBook",type="events.BuyBookEvent")]
public class CatalogList extends TileList{
...
- Ajouter une fonction à CatalogList pour propage l'évènement. Cette fonction sera appelée par les instances d'itemRenderer:
public function dispatchBuyEvent( item:Object ) : void{
var event:BuyBookEvent = new BuyBookEvent();
event.bookData = item;
dispatchEvent( event );
}
- Changer le code du bouton Buy de l'itemRenderer pour qu'il invoke cette fonction :
<mx:Button label="Buy" fillColors="[0x99ff99,0x99ff99]">
<mx:click>
<![CDATA[
(listData.owner as CatalogList).dispatchBuyEvent(data);
]]>
</mx:click>
</mx:Button>
Maintenant, le Button de l'itemRenderer peut simplement invoquer une fonction du composant liste avec la donnée de l'enregistrement lui correspondant. Cela passe la responsabilité de la réaction à cette action sur le composant List.
Flex ActionScript - Passer des paramètres avec un Event personnalisé
Le composant liste dans cet exemple dispatch un event avec de la data. L'application peut ajouter des event listeners en utilisant de l'ActionScript (grâce au tag [Event] dans CatalogList.as) ou en MXML. Le tag [Event] rend la tâche plus facile aux développeurs.
Petit exemple en pratique (avec les sources):
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*" creationComplete="cHandler(event)" viewSourceURL="srcview/index.html">
<mx:XML id="XMLData" source="data.xml"/>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import events.BuyBookEvent;
private function cHandler(event:Event):void{
mylist.addEventListener(BuyBookEvent.BUY_BOOK, alertData);
}
private function alertData(event:BuyBookEvent):void{
Alert.show("Prix: " + event.bookData.price + "€");
}
]]>
</mx:Script>
<local:CatalogList id="mylist" width="560" itemRenderer="BookItemRenderer"
dataProvider="{XMLData.book}" height="350" columnWidth="275" rowHeight="135" buyBook="{alertData(event)}"/>
</mx:Application>
Flex Source Code Download: Télécharger le code source complet de l'application
Petite conclusion sur la communication ItemRenderer / Application
- Les itemRenderer doivent communiquer des actions en utilisant des évènements (Event). Les évènements personnalisés permettent de passer de la data avec l'évènement pour que l'entité qui capte l'évènement ne doive pas aller chercher la data dans l'itemRenderer.
- Les itemRenderer doivent réagir aux changements de la data en faisant des override sur les fonctions set data(). On peut accéder aux valeurs depuis l'intérieur de ces fonction en utilisant listData.owner. Vous pouvez aussi accéder aux data stockées dans des variables static ou dans l'application principale par Application.application.
Articles similaires
- Flex Item Renderer – Communication entre un itemRenderer et l'application
- Flex Item Renderer – Créer un ItemRenderer externe (MXML et ActionScript)
- Flex Item Renderer – Créer un ItemRenderer réutilisable avec listData
- Flex Item Renderer – Modifier la taille d'un item avec des Transition
- Flex Item Renderer – Un itemRenderer optimisé en héritant de UIComponent
Aucun trackbacks pour l'instant






24 mars 2009
Hello,
ton exemple me fait un peu penser à ce que je suis en train de faire actuellement... En gros, on pourrait imaginer en reprenant ton exemple que j'ai 2 catalogList une à coté de l'autre. Une qui représente les livres dispos, l'autre, mes livres favoris. Bien entendu, on retrouvera des doublons de livres.
Plus complexe encore, mon dataProvider ressemble à quelque chose genre
Donc, en gros, j'ai une "liste de liste".
Dans mon itemRenderer, j'ai un bouton supplémentaire qui me permet disons de changer le prix du livre. Comment réussir à mettre à jour l'itemRenderer de mes "favoris" quand je change le prix dans le catalogList des livres dispos ?
J'ai bien essayé en utilisant le dispatchEvent(new Event('foo', true)) et la, j'arrive bien à remonter la modification... par contre, pour la "redescendre" dans l'autre liste, la, je suis coincé.
24 mars 2009
Salut,
problème intéressant. Comme il est précisé, il ne faut pas essayer d'accéder à l'itemRenderer mais plutôt modifier la data qu'il a à afficher. Si tu arrives à faire remonter ta modification, c'est déjà un premier pas. il faut ensuite que tu modifies la data de ton dataProvider favoris. Pour cela, il faut que tu boucles sur ton dataProvider favoris pour trouver l'élément qui correspond à l'élémént que tu as modifié dans la liste de base. Une fois que tu as trouvé cet élément, tu pourra changer son prix directement et l'itemRenderer se mettra à jour.
Par contre, essaie d'utiliser un ArrayCollection au lieu d'un Object, tu aura moins de mal pour les parcours et pour tes tests
Fabien
22 septembre 2010
La solution proposée ici oblige à surcharger la TileList, ou une DataGrid le cas échéant.
Pour éviter celà, j'ai trouvé un site proposant une solution plus simple, utilisant le concept de bubble :
"How to dispatch an event from a custom item renderer" http://nwebb.co.uk/blog/?p=16
Il suffit d'abonner la TileList ou DataGrid ou autre à l'événement BuyBookEvent.
Dans le renderer, à la création de l'event, mettre le paramètre bubble à true, ainsi l'événement sera automatiquement propagé à la TileList (ou DataGrid ou autre).
Dans mon cas, ca fonctionne avec un AdvancedDatagrid
22 septembre 2010
Salut kanai,
effectivement, le bubbling permet de ne pas faire d'héritage (au passage, tu perd les metadatas associées à ta list qui précisent le type d'évent dispatché). Par contre, n'oublies pas de bien stopper la propagation de l'évènement quand tu l'a récupéré car sinon celui-ci va remonter toute la liste d'affichage. Et à chaque fois qu'il remonte la liste d'affichage, la méthode Event::clone() est appélée qui crée une nouvelle instance de l'event, ce qui peut ralentir ton application
Fabien
11 octobre 2010
Serait-il possible d'expliquer un peu le rôle de "criteria", j'ai beau chercher je ne comprend pas bien à quoi il sert. Merci
11 octobre 2010
Salut Rio Grande,
je suppose que tu parles du "criteria" précisé dans un autre tutorial sur les IR, non ? Cette variable sert à définir le pallier à partir duquel il faut (ou pas) afficher les éléments
Fabien
12 octobre 2010
Je parlais bien de cet exemple, en tout cas dans ce qui est présent dans les sources. D'ailleurs pas tous les fichiers sont visibles (quand on click sur "ItemRendererCommunicationB" par exemple).
Mais j'ai utilisé la solution proposée par "kanai" que j'ai pu transposer à mon cas (en ajoutant un event.stopPropagation(); après récupération de l'événement). Je suis nouveau dans le domaine et j'ai eu du mal à comprendre pourquoi il faut que BookItemRenderer implemente IDropInListItemRenderer...
(PS: ça serait cool de corriger le bug qui fait qu'on ne voit pas le champ d'édition des commentaires en blanc sous IE)
8 novembre 2011
Il y a un problème avec le lien des sources à la fin de l'article
8 novembre 2011
Salut,
Cet article est un peu ancien, mieux vaut télécharger le ZIP avec les sources:
http://www.flex-tutorial.fr/wp-content/uploads/ItemRendererCommunicationB/srcview/ItemRendererCommunicationB.zip
Fabien