2010-07-07 3 views
0

Je ne suis pas une personne Javascript normalement, mais j'ai plongé dedans, en lisant Douglas Crockford's book, et en écrivant des bouts triviaux et utiles comme prolongements de Chrome et Node.js (notez que cette question n'est au sujet de aucun d'entre eux). En ce moment, j'essaie de comprendre comment conserver une référence à un objet qui initie une requête AJAX, c'est-à-dire: une fois que j'ai défini le gestionnaire d'événement onload (cela vient d'une extension Chrome, donc je m en utilisant l'objet XMLHttpRequest de base), est-il possible que je puisse renvoyer à MyObject dans l'exemple suivant:Javascript: Comment conserver une référence à un initiateur de requête dans un gestionnaire?

MyObject.prototype = { 
    PerformAction: function() { 
     this.Request = new XMLHttpRequest(); 
     this.Request.open("GET", this.ConstructUrl(), true); 
     // From within ActionResultHandler, 'this' will always be the XMLHttpRequest 
     this.Request.onload = this.ActionResultHandler, 
     this.Request.send(null); 
    } 
} 

Faire cela va exactement à affecter this être l'objet de la demande elle-même, et si je simplement introduire un emballage:

this.Request.onload = function() { ActionResultHandler() }; 

bien, cela ne va tout simplement pas faire quoi que ce soit, parce que l'ActionResultHandler est maintenant hors de portée. La raison pour laquelle je pose cette question est que je n'ai trouvé que des cas triviaux de manipulation d'appel (par exemple manipuler ce que this fait à l'intérieur d'une fonction), mais étant donné que Javascript et AJAX sont littéralement partout, cela doit être un problème connu et simple, mais mon Google-fu me manque ici. En C#, les événements sont invoqués dans le contexte de ceux qui les attachent, pas de l'objet qui déclenche l'événement, donc cela ne se produit pas tous les jours. Peut-être y a-t-il un bien meilleur modèle JS qui évite complètement ce problème?

+1

Je suis vraiment trop tard dans la soirée (lire: ivre) pour répondre correctement à votre question, mais peut-être que vous pouvez profiter de ces articles: http://www.digital-web.com/articles/scope_in_javascript/ et http: //www.quirksmode.org/js/this.html –

+0

voir [Function.prototype.bind] (http://www.google.com/search?hl=fr&q=function.prototype.bind&aq=f&aqi=&aql=&oq = & gs_rfai =) et http://stackoverflow.com/questions/3018943/javascript-object-binding-problem-inside-of-function-prototype-definitions/3019431#3019431 – Anurag

+0

Autant que j'aime quirksmode.org, ce lien ne couvre pas vraiment apply/call, ce qui est ce dont j'avais besoin (bien que le premier le fasse). Merci! –

Répondre

3

Ce n'est pas vraiment clair pour moi quelle variable vous voulez garder une référence. Voici comment vous obtiendriez une référence à MyObject dans votre gestionnaire onload:

MyObject.prototype = { 
    PerformAction: function() { 
     var MyObjectRef = MyObject, 
      ActionResultHandler = this.ActionResultHandler; 

     this.Request = new XMLHttpRequest(); 
     this.Request.open("GET", this.ConstructUrl(), true); 
     // From within ActionResultHandler, 'this' will always be the XMLHttpRequest 
     this.Request.onload = function() { 
       ActionResultHandler.apply(MyObjectRef, arguments); 
      }; 
     this.Request.send(null); 
    } 
} 

Edité

Ok, je relis votre question et il semble que vous voulez exécuter ActionResultHandler dans le contexte de MyObject, J'ai donc modifié mon code pour le faire.

+1

En effet c'est ce que je voulais - je me suis contenté d'assigner le gestionnaire de cette façon: 'this.Request.onload = function (event) {responder.apply (selfReference, [événement, this]); }, 'afin de préserver à la fois' XMLHttpRequestProgressEvent' et 'XMLHttpRequest'. Merci! –

1

Avez-vous essayé ...

this.Request.onload = this.ActionResultHandler.apply(this); 

Je pense que c'est ce que vous cherchez (désolé si ce n'est pas). L'utilisation de .apply(this) pointera ActionResultHandler à Object.

Jetez un coup d'œil à this article sur la reliure pendant que vous y êtes! Cela m'a beaucoup aidé.

+0

Votre extrait définit en fait 'this.Request.onload' pour qu'il soit égal à la valeur de retour de' this.ActionResultHandler' appelée dans le contexte de 'this'. Je ne pense pas que c'est ce qu'il essaie d'accomplir. – lawnsea

+0

Bon point, je ne sais pas ce que je pensais ... – bschaeffer

+0

AFAIK, 'this.ActionResultHandler' serait toujours lié en utilisant la valeur actuelle de' this' .. néanmoins, il était sur la bonne voie, et le lien a aidé, merci! –

Questions connexes