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 :