2012-01-31 2 views
0

Я создаю скрипт, который извлекает несколько каналов 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), данные Tumblr JSON правильно отображаются (см. Контейнеры 2 и 3 в выходном файле html). Если я определяю функцию обратного вызова, я получаю что-то вроде «callbackFunctioName не определено», а затем рендеринг завершается с ошибкой.

Я что-то упустил? Это вопрос о масштабах? И если да, то как я могу обходить его?

Заранее благодарим за любые ответы.

EDIT 1: Обновлен код сценария выше.

+0

Отсортировано самостоятельно. Хитрость заключается в динамическом создании функции обратного вызова в объекте окна, поэтому вы можете ее использовать. Хотя это не Tumblr-специфический (как показано выше), я использую эту технику здесь: http://demo.joomlaworks.gr/allvideos - js, создающий динамические функции обратного вызова, ссылается на http://demo.joomlaworks.gr/ plugins/content/jw_allvideos/includes/js/behaviour.js - Это то, как SoundCloud и Blip.tv внедряются в работу - наслаждайтесь :) – fevangelou

ответ

0

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

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

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

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

В противном случае вы в основном хотите перенести то, что у вас есть в настоящее время, как 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.

+0

Итак, вы говорите, что функция обратного вызова уже должна быть определена в другом месте скрипта, прежде чем получать JSON данные? Конечно, скрипт работает без обратного вызова, но выбор нескольких каналов Tumblr JSON и передача их в одну и ту же переменную не является плохой практикой? – fevangelou

+0

Функция обратного вызова * must * должна быть определена уже, прежде чем пытаться выполнить вызов JSONP (потому что он отправит вам сценарий, который пытается * вызвать * эту функцию обратного вызова). И я бы согласился: использование обратного вызова, вероятно, предпочтительнее, просто позволяя API Tumblr назначать определенную переменную. –

+0

Даже если я вручную определяю функцию обратного вызова (в этом случае, если я просто пишу var javascript = new Function();) в корне сценария, данные JSON по-прежнему неправильно читаются ... – fevangelou

0

не эта линия должна:

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

быть:

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

?

Я не уверен, это выглядит странно для меня.

+0

settings.callback - это просто набор параметров, где мы вызываем скрипт (также известный как файл index.html). – fevangelou

Смежные вопросы