Petite astuce pour YUI3 que je viens de trouver après maintes recherches et tentatives. Le gros problème des sandbox, c'est qu'il est difficile de communiquer de l'une à l'autre. J'ai été confronté au problème suivant : dans une partie de mon code, je crée un nouvel objet à partir d'une de mes classe. Puis, ailleurs, je désires utiliser cet objet. Mais je suis, forcément, dans une nouvelle sandbox. Comment accéder à cet objet ?
Présentation de la situation
YUI().use('maClasse', function(Y) { var objet = new MaClasse({label: 'truc'}); }); //[…] alert(objet.get('label'));
Résultat, l'alerte affiche "undefined" car objet n'existe pas dans cette sandbox.
Première tentative, la variable globale
J'ai d'abord naïvement pensé qu'en mettant mon objet en tant que variable globale, je pourrais y accéder dans ma seconde sandbox :
var objet = null; YUI().use('maClasse', function(Y) { objet = new MaClasse({label: 'truc'}); }); //[…] alert(objet.get('label'));
Erreur, car objet est bien renseigné dans le scope global, mais le code passé à YUI().use n'est exécuté que quand tout les scripts sont chargés de façon asynchrone. De ce fait, quand le parser arrive à la fonction alert(), le code de YUI n'a pas encore été exécuté et window.objet vaut toujours null.
Utilisons les événements personnalisés !!
On se rapproche du but en s'orientant vers les custom events de YUI. YUI3 propose une gestion des évenements perso vraiment très pratique et très simple. On peut faire lacher un évenement de n'importe quel type par tout les objets encapsulés dans YUI. Et on les écoute aussi facilement. La preuve par l'exemple :
YUI().use('event', function(Y) { objet = new MaClasse({label: 'truc'}); // Écoute de l'évenement "MonEvent:estLance" Y.on( "MonEvent:estLance", function(arg) { alert(arg); } ); // On met un timer pour lancer l'évenement plus tard : setTimeout( function() { Y.fire("MonEvent:estLance", 'kikoo'); }, 5000 ); });
Ainsi, 5 secondes après le chargement de la page, une alerte m'affichera "kikoo". J'ai donc tenté cette solution par :
YUI().use('event', function(Y) { Y.on( "MonEvent:estLance", function(obj) { alert(obj); } ); }); YUI().use('event', 'maClasse', function(Y) { var objet = new MaClasse({label: 'truc'}); Y.fire( "MonEvent:estLance", objet ); });
Ça ne fonctionne pas, car les event sont limité au scope de la sandbox… Ah mais ! C'est agaçant !
Évenements globaux
Après pas mal de recherches et de bidouilles, j'ai fini par comprendre le passage de la doc où il est expliqué le fonctionnement des évenements globaux. Et voici donc enfin la solution finale :
YUI().use('event', function(Y) { Y.Global.on( "MonEvent:estLance", function(obj) { alert(obj); } ); }); YUI().use('event', 'maClasse', function(Y) { var objet = new MaClasse({label: 'truc'}); Y.Global.fire( "MonEvent:estLance", objet ); });
Et voilà comment je peux interférer sur des objets construits dans des sandbox différentes dès leur création : faites leur cracher des événements globaux !
YUI3 est un peu compliqué à cause de ces bac à sables hermétiques, mais c'est réellement très puissant ! Bon courage !
Commentaires