Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Actualités

  • Blog de Cyril DURAND, passionné de JavaScript, Ajax, ASP.net et tout ce qui touche au developpement Web Client-Side.

    View Cyril Durand's profile on LinkedIn

    hit counters

Quizz JavaScript - reponse : objet et abonnement d'evenement

Voici les réponses au Quizz JavaScript : objet et abonnement d'événement

Le problème était encore à cause du scope JavaScript, en effet quand un élément DOM déclenche un événement le this de la méthode vaut alors l'élément lui même, c'est à dire dans notre cas le bouton et non l'objet de type CS.UI.MonControl.

Comment faire pour remédier à ce problème ? il faut utiliser la méthode apply de l'objet Function. Soit :

_createDom : function(){ this._button = document.createElement('button'); this._button.appendChild(document.createTextNode('button')); $addHandler(this._button, 'click', function(self){ return function(){ (function(){ this._btnclick(); }).apply(self, arguments); }; }(this) ); this._element.appendChild(this._button); this._element.appendChild(document.createElement('br')); }, _btnclick : function(){ this._dummyMethod(); },

Cet enchainement de fonction ne rend pas le code très agréable à lire ni même à écrire. Heureusement Microsoft Ajax library, comme quasi tous les frameworks client, possèdent une méthode similiaire : Function.createDelegate(this, this._btnclick)  (non documenté) 

Mais je vous déconseille d'écrire ce code :

_createDom : function(){ this._button = document.createElement('button'); this._button.appendChild(document.createTextNode('button')); // c'est mal !! $addHandler(this._button, 'click', Function.createDelegate(this, this._btnclick)); this._element.appendChild(this._button); this._element.appendChild(document.createElement('br')); }, _btnclick : function(){ this._dummyMethod(); },

Pourquoi ? Imaginez que vous avez envie de vous désabonner de l'événement 'click', pour cela il vous faut l'instance de la fonction avec laquelle on s'est abonné à l'événement, c'est à dire le résultat de la méthode Function.createDelegate. Il faut donc créer une variable contenant ce delegate, ma convention est de l'appeller nomdelafunction$delegate :

CS.UI.MonControl = function(element){ CS.UI.MonControl.initializeBase(this, [element]); this._btnclick$delegate = Function.createDelegate(this, this._btnclick); } CS.UI.MonControl.prototype = { // ... _createDom : function(){ this._button = document.createElement('button'); this._button.appendChild(document.createTextNode('button')); $addHandler(this._button, 'click', this._btnclick$delegate); this._element.appendChild(this._button); this._element.appendChild(document.createElement('br')); }, // ... } CS.UI.MonControl.registerClass('CS.UI.MonControl', Sys.UI.Control);

Pour en savoir plus :

Posted: mardi 14 août 2007 01:45 par cyril
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

FREMYCOMPANY a dit :

Très bonne remarque sur la combinaison addHandler / toDelegate.

A noter tout de même que généralement, on n'a pas besoin de se désabonner alors autant ne pas créer de variables supplémentaires pour rien ;)

# août 14, 2007 14:27

cyril a dit :

On n'a pas besoin de se désabonner ??? je ne suis absolument pas d'accord ! Il faut se désabonner pour éviter les fuites mémoires (principalement avec IE) c'est pour ca que l'équipe Atlas à implémenté l'interface IDisposable qui est implémenté sur Sys.Component (classe de base pour Sys.UI.Control).

La méthode dispose sera alors appelé quand on a plus besoin du controle, généralement lorsqu'on change de page.

Si tu regardes le code de mon controle il y a bien un $clearHandlers sur le bouton au niveau du dispose, le $clearHandlers va supprimer toutes les functions attaché à partir de $addHandler. Mais si l'on veut désabonner une méthode précise (ce qui m'est déjà arrivé plus d'une fois ...) il nous faut l'instance exacte.

# août 14, 2007 14:50

FREMYCOMPANY a dit :

Heu, je ne vois pas la méthode clearHandlers...

Et puis de toute facon, les fuites de mémoire, ce n'est pas mon problème, c'est celui du navigateur... Moi je lui ai rien demandé ;)

J'ai consulté de nombreux site et jamais je n'en ai vu un qui utilisait une fonction comme clearHandler, je peux te l'assurer, et je n'ai jamais eu de problème en naviguant dessus... Même si ils sont "Web 2", comme on dit.

# août 14, 2007 15:57

FREMYCOMPANY a dit :

A noter aussi : plutot que d'abonner, désabonner, je préfère toujours la fonction de tri :

function(e) { var e=e?e:event; if (gnagna) { o1.f(e) } else if (gnagna2) { o2.f(e) } else { f1(e) } }

# août 14, 2007 16:01

cyril a dit :

>>http://blogs.developpeur.org/cyril/archive/2007/08/12/quizz-javascript-objet-et-abonnement-d-evenement.aspx

dispose : function(){

  CS.UI.MonControl.callBaseMethod(this, 'dispose');

  $clearHandlers(this._button);

},

La plupart des frameworks implémentent une chose du genre, avec prototype il me semble que c'est stopObserving (qui est peut etre appelé automatiquement sur le window.onunload)  

il y a un temps de lien parlant du problème, notamment : http://jibbering.com/faq/faq_notes/closures.html#clMem

et si t'en veux plus : http://www.google.com/search?hl=en&rls=com.microsoft%3Aen-US&q=detachEvent+removeEventListener+memory+leak

# août 14, 2007 16:22
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- TCB : Travailler en équipe sans réseau par The Mit's Blog le il y a 15 minutes

- Accès anonyme et les pages Forms / viewlsts.aspx... par Nicolas Humann le il y a 4 heures et 8 minutes

- l'Atelier 4 du coach C# est disponible par Bernard Fedotoff le il y a 5 heures et 44 minutes

- [WPF] Formatter l’affichage lors d’un binding, via StringFormat par Thomas Lebrun le il y a 10 heures et 46 minutes

- WSC08 : Le bilan, Les Photos, Les Webcasts à voir ou à revoir par Blog de Daniel TIZON [daniel] le il y a 19 heures et 53 minutes

- SharePoint et ses DB : Avez vous pensé à les "Tweaker" ? par The Mit's Blog le il y a 20 heures et 22 minutes

- NTttcp : Mesurer la vitesse d'un réseau par Blog d'Olivier Huet le il y a 20 heures et 47 minutes

- Un nouveau quizz par Matthieu MEZIL le il y a 23 heures et 31 minutes

- Webcast ADO.NET Data Services par Matthieu MEZIL le il y a 23 heures et 34 minutes

- edmx : mise à jour du modèle depuis la base par Matthieu MEZIL le 10-06-2008, 17:47