2011-03-23 5 views
0

Je suis assez nouveau à Javascript et ne peux pas pour ma vie découvrir pourquoi les propriétés d'objet suivantes ne transfèrent pas.Javascript - propriétés de l'objet ne pas transférer

J'appelle l'objet comme suit:

var URL = "TABLE=_Products&COLUMNS=price_Qty,Sale&MATCH=internal_Model&ROWS="+itemnum ; 
var ITEM = new get_Database_Info(URL) ; 

et get_Database_Info est:

function get_Database_Info(PARAMS) { 
    alert(toString(this)); 
    var URL = document.location.protocol+'//'+document.location.host+'/Catalog/Tools/ajax_Database_Request.php' ; 

    if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari 
      xmlhttp=new XMLHttpRequest(); 
     } 
    else{// code for IE6, IE5 
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
     } 

    if(!xmlhttp){alert('Error: Cannot send XML request.');} 
     xmlhttp.onreadystatechange=function() { 

      if (xmlhttp.readyState==4 && xmlhttp.status==200){ 
       alert(toString(this)); 
       var RESPONSE = xmlhttp.responseText ; 
       RESPONSE = RESPONSE.replace(/^\s+/, ''); 
       var ARR = RESPONSE.split('||') ; 
       ARR.pop() ; 
       for(var i=0; i<ARR.length; i++){ 
        var temparr1 = ARR[i].split('=') ; 
        var NUM = temparr1[0] ; 
        this[NUM] = new Array() ; 
         var temparr2 = temparr1[1].split('/|') ; 
         temparr2.shift() ; 
          for(var x=0; x<temparr2.length; x++){ 

           var temparr3 = temparr2[x].split('??') ; 

           this[NUM][temparr3[0]] = temparr3[1] ; 

          } 
       } 

      } 
     } 

    xmlhttp.open("POST", URL, true); 
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
    xmlhttp.setRequestHeader("Content-length", PARAMS.length); 
    xmlhttp.setRequestHeader("Connection", "close"); 
    xmlhttp.send(PARAMS); 

}

J'ai vérifié que toutes les propriétés sont 'ceci' dans le portée de get_Database_Info mais ils ne sont pas transférés à ITEM.

+0

Le problème consistait à appeler une requête asynchrone. Je vois comment cela fonctionne maintenant TYVM à toutes les affiches. Étrange cependant que le script spécifique continue à s'exécuter même si j'ai pratiquement exigé que l'objet obtienne ces propriétés en premier. –

Répondre

0

Quand vérifiez-vous le contenu de l'objet? La requête est asynchrone, vous devez donc attendre que le rappel ait traité la réponse avant qu'il n'y ait des propriétés dans l'objet.

Si vous recherchez les propriétés immédiatement après la création de l'objet, elles ne seront jamais présentes. Même si la réponse est vraiment rapide, la première fois que le rappel peut s'exécuter est lorsque vous quittez la fonction où vous avez créé l'objet, de sorte que le navigateur récupère le contrôle.

0

Je parierais que la lorsque la fonction qui est attaché à onreadystatechange court que this n'est plus attaché à l'objet qui est créé dans le constructeur, mais est probablement attaché à l'objet global ou l'objet xmlhttp. Je voudrais essayer d'utiliser le modèle var that=this:

function get_Database_Info(PARAMS) { 
    alert(toString(this)); 
    var URL = document.location.protocol+'//'+document.location.host+'/Catalog/Tools/ajax_Database_Request.php' ; 

    if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari 
      xmlhttp=new XMLHttpRequest(); 
     } 
    else{// code for IE6, IE5 
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
     } 

    var that=this; // value of that will be stored in the closure 

    if(!xmlhttp){alert('Error: Cannot send XML request.');} 
     xmlhttp.onreadystatechange=function() { 
      if (xmlhttp.readyState==4 && xmlhttp.status==200){ 
       alert(toString(that)); 
       var RESPONSE = xmlhttp.responseText ; 
       RESPONSE = RESPONSE.replace(/^\s+/, ''); 
       var ARR = RESPONSE.split('||') ; 
       ARR.pop(); 
       var arrLength = ARR.length; // always precompute array length 
       for(var i=0; i<ARR.length; i++){ 
        var temparr1 = ARR[i].split('=') ; 
        var NUM = temparr1[0] ; 
        // that is actually equal to the object that I created 
        // in the constructor. 
        that[NUM] = new Array() ; 
        var temparr2 = temparr1[1].split('/|') ; 
        temparr2.shift() ; 
        var arrayLength = temparr2.length; // always precompute length 
        for(var x=0; x<arrayLength; x++){ 
         var temparr3 = temparr2[x].split('??') ; 
         that[NUM][temparr3[0]] = temparr3[1] ; 
        } 
       } 
      } 
     } 

    xmlhttp.open("POST", URL, true); 
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
    xmlhttp.setRequestHeader("Content-length", PARAMS.length); 
    xmlhttp.setRequestHeader("Connection", "close"); 
    xmlhttp.send(PARAMS); 

En outre, comme il est indiqué dans les commentaires, lorsque vous itérez les valeurs dans un tableau pour une boucle for, vous ne devriez pas utiliser array.length directement, comme length méthode sera appelée à chaque fois à travers la boucle, ce qui ajoute beaucoup de travail inutile. De même, comme le note @Guffa, la fonction qui ajoute les valeurs est appelée de manière asynchrone, donc les propriétés n'existeront pas tant que XmlHttpRequest ne sera pas terminé, et c'est un anti-pattern très dangereux. Je conseillerais fortement contre. Il est préférable que votre constructeur fasse une requête synchrone pour les données.

Questions connexes