Проблема контекста JSONP - PullRequest
0 голосов
/ 16 июня 2010

Я использую javascript autocomplete () в скрипте greasemonkey. Само по себе это работает правильно, но я не хочу добавлять 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);

Я удалил не соответствующий код. Теперь, когда вызывается preSuggest, он добавляет скрипт в заголовок и обходит проблему междомена. Теперь, когда данные получены обратно, вызывается JSONcallback. Я могу использовать данные, но когда 'Suggest' - я не могу использовать массив this.keywords или this.suggest_url Я думаю, это потому, что JSONcallback и Suggest вызываются в другом контексте.

Как мне заставить это работать?

1 Ответ

0 голосов
/ 16 июня 2010

Когда вы вызываете функцию непосредственно из прототипа, контекст для this отсутствует, поэтому, когда возвращается вызов JSONP, он вызывает autosuggest.prototype.JSONCallback, но эта функция не может вызвать this.suggest().

Вместо этого я бы предложил создать функцию-обертку:

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

или создайте один глобальный autosuggest объект и используйте его в качестве обратного вызова:

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

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