2011-09-23 2 views
0

Salut, je commence à utiliser le modèle de conception javascript singleton, mais j'ai des problèmes de portée. Ici, je suis en train d'expérimenter avec un petit ajax, récupérer et stocker singleton. Depuis une fonction dans le singleton j'appelle une autre fonction (this.ready, appelée quand l'ajax a récupéré et stocké les données) mais il semble que "this" ne se réfère pas au singleton, mais plutôt à "Object # XMLHttpRequest "selon le débogueur chrome, firefox dit juste qu'il est indéfini.javascript singleton problèmes de portée avec "this"

  var mag = { 
       magObj: [], // object to store the retrieved json data 

       getData: function(){ 
        request = getHTTPObject(), // defined externally 
        request.onreadystatechange = this.setData; 
        request.open("POST", "be.php", true); 
        request.send(null); 
       }, 

       setData: function(){ 
        if (request.readyState == 4) 
        { 
         this.magObj = JSON.parse(request.responseText); 
         this.ready(); // this line yields the error, seems "this" does not refer to the singleton 

        } 
        else if (request.readyState == 1) 
        { 

        } 
       }, 

       ready: function() { 
        console.log('ready'); 
       }, 

       construct: function(){ 
        this.getData(); 
       }, 
      } 

Aussi, si je tente de déclarer la getHTTPObject() comme une variable singleton dans la partie supérieure, au lieu d'utiliser la variable globale i obtenir l'erreur Impossible de lire la propriété « readyState » de non défini. Encore une fois, il est « ce » getHTTPObject qui semble être indéfini, même si je l'ai mis en haut:

 var mag = { 
      magObj: [], 
      request: getHTTPObject(), 

      getData: function(){ 

       this.request.onreadystatechange = this.setData; 
       this.request.open("POST", "be.php", true); 
       this.request.send(null); 
      }, 

      setData: function(){ 
       if (this.request.readyState == 4) // debugger says this.request is undefined 
       { 
        this.magObj = JSON.parse(this.request.responseText); 

       } 
       else if (this.request.readyState == 1) 
       { 

       } 
      }, 

      construct: function(){ 
       this.getData(); 
      }, 
     } 
+1

"this" change de javascript en fonction de la fonction d'appel. Consultez cette réponse http://stackoverflow.com/questions/4886632/what-does-var-that-this-mean-in-javascript – David

Répondre

1

S'il est un singleton vous pouvez essayer

  var mag = { 
      magObj: [], // object to store the retrieved json data 

      getData: function(){ 
       request = getHTTPObject(), // defined externally 
       request.onreadystatechange = this.setData; 
       request.open("POST", "be.php", true); 
       request.send(null); 
      }, 

      setData: function(){ 
       if (request.readyState == 4) 
       { 
        this.magObj = JSON.parse(request.responseText); 
        mag.ready(); // this line yields the error, seems "this" does not refer to the singleton 

       } 
       else if (request.readyState == 1) 
       { 

       } 
      }, 

      ready: function() { 
       console.log('ready'); 
      }, 

      construct: function(){ 
       this.getData(); 
      }, 
     } 
1

# 1
setData est une fonction de rappel pour l'objet XMLHttpRequest. Il est donc exécuté dans le champ de l'objet XMLHttpRequest. Utilisez mag au lieu de this.

# 2
Identique #1: this fait référence à la XMLHttpRequest, plutôt que de vous mag variables.

1

Pour résoudre le problème de la portée, vous devez utiliser les concepts de fermetures en javascript. essentiellement une portée où les fonctions ont accès aux propriétés et méthodes dans le contexte qui a créé cette fonction .. ok pour une explication plus claire .. essayez l'initialisation de votre objet mag en fonction ..

var mag = function(){ 
    var magObj = []; 
    var getData = function(){ 
     //here you'll have access to the magObj collection 
    }; 
} 

Le précédent est un classique exemple d'une fermeture javascript. Bien sûr, vous instanciez l'objet mag simplement comme une invocation de fonction mag();

Espérons que cela aide.