2009-05-08 9 views
3

J'ai ce code pour faire une demande ajax à un webservice:La valeur de « ceci » dans une fonction de rappel

var MyCode = { 
    req: new XMLHttpRequest(), // firefox only at the moment 

    service_url: "http://url/to/Service.asmx", 

    sayhello: function() { 
     if (this.req.readyState == 4 || this.req.readyState == 0) { 
      this.req.open("POST", this.service_url + '/HelloWorld', true); 
      this.req.setRequestHeader('Content-Type','application/json; charset=utf-8'); 
      this.req.onreadystatechange = this.handleReceive; 
      var param = '{}'; 
      this.req.send(param); 
     } 
    }, 

    handleReceive: function() { 
     if (this.req.readyState == 4) { 
      // todo: using eval for json is dangerous 
      var response = eval("(" + this.req.responseText + ")"); 
      alert(response); 
     } 
    } 
} 

Elle est appelée avec MyCode.sayhello() bien sûr.

Le problème est que "req n'est pas défini" à la première ligne de la fonction handleReceive. Il est appelé 4 fois, donc je sais que le code ci-dessus envoie la requête au serveur.

Comment puis-je résoudre ce problème?

+0

Devrait être this.responseText .. pas this.req.responseText (puisque 'this' fait référence à l'objet XHR) – James

Répondre

4

Problème de fermeture classique. Lorsque vous recevez le rappel, la fermeture fait référence à l'objet HTTP.

Vous pouvez faire ce qui suit comme quelqu'un suggère:

var that = this; 
this.req.onreadystatechange = function() { this.handleReceive.apply(that, []); }; 

ou tout simplement faire ce qui suit:

var that = this; 
this.req.onreadystatechange = function() { that.handleReceive(); }; 
+0

Merci! Pour mémoire: le code de travail est: \t \t handleReceive: function() { \t \t \t if (this.readyState == 4) { \t \t \t \t réponse var = eval ("(" + this.responseText + ")"); \t \t \t \t alerte (réponse); \t \t \t} \t \t} – Tominator

2

Vous pouvez résoudre que par une makeing variable ce référent dans MyCode. Comme

var MyCode = { 
    req: new XMLHttpRequest(), // firefox only at the moment 

    self = this 

    ... 
} 

Ensuite, vous pouvez vous référer à soi au lieu de cela.

0

Modifier ceci:

this.req.onreadystatechange = this.handleReceive; 

à ceci:

var self = this; 
this.req.onreadystatechange = function() { self.handleReceive(); } 

Cela crée une fermeture qui devrait résoudre vos problèmes.

0

vous devriez être en mesure de le faire fonctionner en changeant

this.req.onreadystatechange = this.handleReceive; 

à

var that = this; 
this.req.onreadystatechange = function() { this.handleReceive.apply(that, []); }; 

Function.prototype.apply peut être utilisé pour appeler une fonction alors explicitement this et les arguments de la fonction.

Questions connexes