Pergunta

Has anyone previously figured out how to send a (JQuery plugin) object-scoped method as a Google API callback? E.g. for the PageSpeed API.

All the samples show you sending the name of a global function, but I want to somehow send the specific instance method, (or a way to re-look up the JQuery object).

This is based on their sample:

 var s = document.createElement('script');
 s.type = 'text/javascript';
 s.async = true;
 var query = [
   'url=' + url,
   'callback=runCallbacks',
   'key=' + settings.api_key,
 ].join('&');
 s.src = API_URL + query;
 document.head.insertBefore(s, null);

So I want to achieve is something like this call:

 $('div.jq-google-plugin).MyGooglePlugin('callback',result);

I am setting up the call to Google from within my plugin's init method.

e.g. I tried this - but this produces a 400 Bad Request from Google API.

 var query = [
   'url=' + url,
   'callback='+ encodeURI('function(result){$(\'div.jq-google-plugin\').MyGooglePlugin(\'callback\',result);}’,
   'key=' + settings.api_key,
 ].join('&');

What I don’t really want to have to do is create some name-mangled global just to catch the responses for each plugin instance, but I think this is the only way? (This works BTW.)

 var query = [
   'url=' + url,
   'callback=myUniqueGlobalCallback',
   'key=' + settings.api_key,
 ].join('&');
 myUniqueGlobalCallback = function(result){$('div.jq-google-plugin).MyGooglePlugin('callback',result);}

Thanks in advance for any insights! I guess the solution may not be Google API-specific, but could be around why it rejects any thing other than a global function name.

Foi útil?

Solução

jQuery has pretty good support for JSONP. You should use that instead of injecting the script element yourselves. With that you don't even need to care about the callback, and the response will automatically get routed to your success callback.

jQuery.fn.MyGooglePlugin = function() {
    $.ajax('<url>', {
        dataType: 'jsonp',
        data: {
            key: 'api-key'
        }
        success: function(response) {
            console.log(response);
        }
    });
};

Outras dicas

What I don’t really want to have to do is create some name-mangled global just to catch the responses for each plugin instance, but I think this is the only way?

That's the only way. The problem here is that what you are doing is a JSONP call. That means you aren't actually calling any javascript. You are dynamically adding a new script element to the page. That script element will load the javascript in the url immediately and the javascript will look something like this:

yourCallback({data: "Some Data"});

Because whatever yourCallback is has to be a string for this to work, you can't pass in an object. There is library support for what you are trying to do, but behind the scenes, that's the way it works, because that's the only way it can work.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top