J'ai besoin d'accéder à this
à partir de mon gestionnaire setInterval
prefs: null,
startup : function()
{
// init prefs
...
this.retrieve_rate();
this.intervalID = setInterval(this.retrieve_rate, this.INTERVAL);
},
retrieve_rate : function()
{
var ajax = null;
ajax = new XMLHttpRequest();
ajax.open('GET', 'http://xyz.com', true);
ajax.onload = function()
{
// access prefs here
}
}
Comment puis-je accéder à this.prefs dans ajax.onload
?
La ligne setInterval devrait ressembler à ceci: -
this.intervalID = setInterval(
(function(self) { //Self-executing func which takes 'this' as self
return function() { //Return a function in the context of 'self'
self.retrieve_rate(); //Thing you wanted to run as non-window 'this'
}
})(this),
this.INTERVAL //normal interval, 'this' scope not impacted here.
);
Edit : Le même principe s’applique à "onload
". Dans ce cas, son code commun pour le code "externe" a peu d'effet, il configure simplement la demande et l'envoie ensuite. Dans ce cas, la surcharge supplémentaire liée à une fonction supplémentaire, comme dans le code ci-dessus, est inutile. Votre taux de récupération devrait ressembler davantage à ceci: -
retrieve_rate : function()
{
var self = this;
var ajax = new XMLHttpRequest();
ajax.open('GET', 'http://xyz.com', true);
ajax.onreadystatechanged= function()
{
if (ajax.readyState == 4 && ajax.status == 200)
{
// prefs available as self.prefs
}
}
ajax.send(null);
}
this.intervalID = setInterval(this.retrieve_rate.bind(this), this.INTERVAL);
Le comportement par défaut de setInterval
consiste à se connecter au contexte global. Vous pouvez appeler une fonction membre en enregistrant une copie du contexte actuel. Dans retrieve_rate, la variable this
sera correctement liée au contexte d'origine. Voici à quoi ressemblerait votre code:
var self = this;
this.intervalID = setInterval(
function() { self.retrieve_rate(); },
this.INTERVAL);
Conseil bonus: pour une référence de fonction simple (par opposition à une référence d'objet ayant une fonction membre), vous pouvez modifier le contexte en utilisant les méthodes call
ou apply
de JavaScript.
Grâce à l’amélioration de la prise en charge du navigateur, il est maintenant temps d’utiliser l’amélioration EcmaScript 6, méthode de la flèche =>
, pour conserver this
correctement.
startup : function()
{
// init prefs
...
this.retrieve_rate();
this.intervalID = setInterval( () => this.retrieve_rate(), this.INTERVAL);
},
L'utilisation de la méthode => préserve la this
lorsque retrieve_rate()
est appelé par l'intervalle. Pas besoin de funky ou de passer this
dans les paramètres
Ce serait la solution la plus propre, car la plupart du temps, vous souhaiterez réellement changer le contexte this pour vos appels de méthode consécutifs:
En outre, il est plus facile de saisir le concept de.
// store scope reference for our delegating method
var that = this;
setInterval(function() {
// this would be changed here because of method scope,
// but we still have a reference to that
OURMETHODNAME.call(that);
}, 200);
Avec les navigateurs modernes, la méthode setInterval autorise des paramètres supplémentaires qui sont transmis à la fonction spécifiée par func à l'expiration du délai.
var intervalID = scope.setInterval (func, delay [ param1, param2, ...]);
Par conséquent, une solution possible peut être:
this.intervalID = setInterval(function (self) {
self.retrieve_rate();
}, this.INTERVAL, this);
Une démo:
var timerId;
document.querySelector('#clickMe').addEventListener('click', function(e) {
timerId = setInterval(function (self) {
self.textContent = self.textContent.slice(0, -1);
if (self.textContent.length == 0) {
clearInterval(timerId);
self.textContent = 'end..';
}
}, 250, this);
})
<button id="clickMe">ClickMe</button>
prefs: null,
startup : function()
{
// init prefs
...
this.retrieve_rate();
var context = this;
this.intervalID = setInterval(function()
{
context.retrieve_rate();
}, this.INTERVAL);
},
retrieve_rate : function()
{
var ajax = null;
ajax = new XMLHttpRequest();
ajax.open('GET', 'http://xyz.com', true);
var context = this;
ajax.onload = function()
{
// access prefs using context.
// e.g. context.prefs
}
}