Функция обратного вызова "не определена" - PullRequest
0 голосов
/ 01 февраля 2012

Я создаю скрипт, который выбирает несколько каналов JSON из Tumblr и создает списки HTML на основе этих данных. Довольно простая концепция.

Вот вывод: http://fotis.co/tumblr/index.html

Скрипт частично работает, так как я спотыкаюсь о проблемах "функция обратного вызова не определена". Это происходит только тогда, когда я выбираю функцию обратного вызова при запросе канала Tumblr JSON. По умолчанию, если вы не задаете функцию обратного вызова через API Tumblr, возвращаемый объект JSON назначается переменной с именем tumblr_api_read. Таким образом, JSON фактически возвращает:

var tumblr_api_read = {the JSON object data goes here};

Если я использую функцию обратного вызова, данные JSON возвращаются так (как и ожидалось):

callbackFunctionName({the JSON object data goes here});

Если вы посмотрите код скрипта здесь http://fotis.co/tumblr/tumblr.js:

/* Read Tumblr */

function ready(cb) {
    /in/.test(document.readyState) ? setTimeout('ready('+cb+')', 9) : cb();
}

function getTumblrFeed(params) {
    /*
    Legend:
    start - The post offset to start from. The default is 0.
    num - The number of posts to return. The default is 20, and the maximum is 50.
    type - The type of posts to return. If unspecified or empty, all types of posts are returned. Must be one of text, quote, photo, link, chat, video, or audio.
    id - A specific post ID to return. Use instead of start, num, or type.
    filter - Alternate filter to run on the text content. Allowed values:
        text - Plain text only. No HTML.
        none - No post-processing. Output exactly what the author entered. (Note: Some authors write in Markdown, which will not be converted to HTML when this option is used.)
    tagged - Return posts with this tag in reverse-chronological order (newest first). Optionally specify chrono=1 to sort in chronological order (oldest first).
    search - Search for posts with this query.
    */
    if(params.blogurl) var blogurl = params.blogurl;
    if(params.postcount) var num = params.postcount;
    var jsonurl = document.location.protocol+ '//' +blogurl+ '/api/read/json?num=' +num;
    if(params.type) jsonurl += '&type=' + params.type;
    if(params.tagged) jsonurl += '&tagged=' + params.tagged;
    if(params.search) jsonurl += '&search=' + params.search;
    if(params.callback) jsonurl += '&callback=' + params.callback;
    var jsonfeedscript = document.createElement('script');
    jsonfeedscript.setAttribute('charset', 'utf-8');
    jsonfeedscript.setAttribute('type', 'text/javascript');
    jsonfeedscript.setAttribute('async', 'true');
    jsonfeedscript.setAttribute('src', jsonurl);
    return jsonfeedscript;
}

function renderResults(settings) {
    var tumblrObj = (settings.callback) ? settings.callback : tumblr_api_read;

    var i = 0;
    var c = document.getElementById(settings.container);

    for(i; i<tumblrObj.posts.length; i++){
        // URL
        var postUrl = tumblrObj.posts[i]['url-with-slug'];
        // Title
        if(tumblrObj.posts[i]['regular-title']){
            var postTitle = tumblrObj.posts[i]['regular-title'];
        } else if(tumblrObj.posts[i]['quote-text']){
            var postTitle = tumblrObj.posts[i]['quote-text'];
        } else if(tumblrObj.posts[i]['link-text']){
            var postTitle = tumblrObj.posts[i]['link-text'];
        } else if(tumblrObj.posts[i]['audio-caption']){
            var postTitle = tumblrObj.posts[i]['audio-caption'];
        } else if(tumblrObj.posts[i]['photo-caption']){
            var postTitle = tumblrObj.posts[i]['photo-caption'];
        } else if(tumblrObj.posts[i]['video-caption']){
            var postTitle = tumblrObj.posts[i]['video-caption'];
        } else if(tumblrObj.posts[i]['conversation-text']){
            var postTitle = tumblrObj.posts[i]['conversation-text'];
        } else {
            var postTitle = '';
        }
        // Date
        var postDate = tumblrObj.posts[i]['date']; // or: date-gmt, unix-timestamp
        // Type
        var postType = tumblrObj.posts[i]['type'];
        // Output
        var output = settings.theme.replace("{postUrl}",postUrl).replace("{postTitle}",postTitle).replace("{postDate}",postDate);
        c.innerHTML += output;
    }

    // Hide the loader
    var l = document.getElementById(settings.loader);
    c.removeChild(l);
}

function readTumblr(settings) {
    // Load JSON data
    var head = document.getElementsByTagName('head')[0];
    var jsonfeedscript = getTumblrFeed(settings);
    head.appendChild(jsonfeedscript);

    jsonfeedscript.onload = function(){
        renderResults(settings);
    }
}

Вы увидите, что я проверяю, вызывается ли канал JSON с помощью функции обратного вызова (внутри readTumblr ()), в противном случае я просто использую объект по умолчанию "tumblr_api_read". Если функция обратного вызова не определена в месте инициализации скрипта (внутри index.html), данные JSON Tumblr будут правильно отображены (см. Контейнеры 2 и 3 в выводе html). Если я определю функцию обратного вызова, я получу что-то вроде «callbackFunctioName не определено», и тогда рендеринг завершится неудачей.

Я что-то здесь упускаю? Это проблема сферы? И если так, как я могу обойти это?

Заранее спасибо за любые ответы.

РЕДАКТИРОВАТЬ 1 : обновленный код сценария выше.

Ответы [ 2 ]

0 голосов
/ 01 февраля 2012

Не должна ли эта строка:

tumblrObj = (settings.callback) ? settings.callback : tumblr_api_read

быть:

tumblrObj = (settings.callback) ? settings.callback() : tumblr_api_read

Я не уверен, мне это кажется странным.

0 голосов
/ 01 февраля 2012

Если вы предоставите обратный вызов для JSONP API, вы получите фрагмент JavaScript, который вызывает любую функцию, которую вы предоставили с данными JSON в качестве аргумента. Как вы заметили:

callbackFunctionName({the JSON object data goes here});

Система JSONP / callback зависит от вашего кода , уже определившего функцию callbackFunctionName, так что есть, что вызвать. Идея состоит в том, что вы помещаете свой код, который должен работать с данными Tumblr, в эту функцию обратного вызова.

Если вы предпочитаете работать с var tumblr_api_read способом, просто не указывайте обратный вызов.

В противном случае вы бы хотели переместить то, что у вас есть, как jsonfeedscript.onload, в любую функцию, которую вы определяете как обратный вызов. Например, если вы дали Tumblr API параметр «обратного вызова» myCallback, ваш код должен выглядеть примерно так:

function myCallback(tumblrObj) {
    // Your code that reads the JSON and inserts the HTML
}

Тогда вам больше не нужно звонить myCallback себе . Вы просто делаете запрос JSONP, вставляя тег script, и API Tumblr вернет вам скрипт, который вызывает myCallback и передает данные JSON.

...