2010-06-16 5 views
0

J'utilise une saisie semi-automatique javascript() dans un script greasemonkey. Sur lui-même cela fonctionne correctement mais je ne veux pas ajouter JSONP parce que je veux les données d'un autre domaine. Le code (extrait):Problème de contexte JSONP

function autosuggest(url) 
{ 
    this.suggest_url = url; 
    this.keywords = []; 

    return this.construct(); 
}; 

autosuggest.prototype = 
{ 
    construct: function() 
    { 
     return this; 
    }, 

    preSuggest: function() 
    { 
     this.CreateJSONPRequest(this.suggest_url + "foo"); 
    }, 

    CreateJSONPRequest: function(url) 
    { 
     var headID = document.getElementsByTagName("head")[0];   
     var newScript = document.createElement('script'); 
     newScript.type = 'text/javascript'; 
     newScript.src = url +'&callback=autosuggest.prototype.JSONCallback'; 
     //newScript.async = true; 
     newScript.onload = newScript.onreadystatechange = function() {   
      if (newScript.readyState === "loaded" || newScript.readyState === "complete") 
      { 
       //remove it again 
       newScript.onload = newScript.onreadystatechange = null; 
       if (newScript && newScript.parentNode) { 
        newScript.parentNode.removeChild(newScript); 
       } 
      } 
     } 

     headID.appendChild(newScript); 
    }, 

    JSONCallback: function(data) 
    { 
     if(data) 
     { 
      this.keywords = data; 
      this.suggest(); 
     } 
    }, 

    suggest: function() 
    { 
     //use this.keywords 
    } 
}; 

//Add suggestion box to textboxes 
window.opera.addEventListener('AfterEvent.load', function (e) 
{ 
    var textboxes = document.getElementsByTagName('input'); 
    for (var i = 0; i < textboxes.length; i++) 
    { 
     var tb = textboxes[i]; 
     if (tb.type == 'text') 
     {  
      if (tb.autocomplete == undefined || 
       tb.autocomplete == '' || 
       tb.autocomplete == 'on') 
      { 
       //we handle autosuggestion 
       tb.setAttribute('autocomplete','off');  
       var obj1 = new autosuggest("http://test.php?q=");    
      } 
     } 
    } 
}, false); 

Je supprimé pas le code correspondant. Maintenant, lorsque 'preSuggest' est appelé, il ajoute un script à l'en-tête et contourne le problème du crossdomain. Maintenant, lorsque les données sont reçues, le 'JSONcallback' est appelé. Je peux utiliser les données, mais quand "Suggérer" est je ne peux pas utiliser le tableau this.keywords ou this.suggest_url. Je pense que c'est parce que 'JSONcallback' et 'Suggest' sont appelés dans un contexte différent.

Comment puis-je obtenir ce travail?

Répondre

0

Lorsque vous appelez une fonction sur le prototype directement, il n'y a pas de contexte pour this, par conséquent, lorsque l'appel est renvoyé JSONP, il appelle autosuggest.prototype.JSONCallback, mais cette fonction ne peut pas appeler this.suggest().

Au lieu de cela, je vous suggère de créer une fonction d'emballage:

function JSONCallback(data) { 
    var as = new autosuggest(); 
    as.keywords = data; 
    as.suggest(); 
} 

ou, créer un seul objet global autosuggest et l'utiliser comme le rappel:

var globalAS = new autosuggest("http://example/?q="); 

// inside the CreateJSONPRequest function, change this line: 
newScript.src = url +'&callback=globalAS.JSONCallback'; 
+0

Votre premier exemple crée une nouvelle autosuggest objet mais je veux garder mon 'ancien' objet pour d'autres données telles que suggest_url. Je crée plusieurs objets autosuggest pour chaque élément d'entrée sur la page. N 'y a-t-il pas une autre solution? – RvdK

+0

à court de créer des variables globales pour chaque objet dont vous avez besoin, puis de leur donner un nom afin qu'ils puissent se référencer (par exemple: 'var as1 = new autosuggest(); as1.name = 'as1';' alors je ne peux pas vraiment Pensez à n'importe quoi maintenant, peut-être pourriez-vous vous réorganiser pour ne pas avoir besoin d'objets AS persistants? – nickf