2011-07-05 6 views
3

UPDATE 1:Когда данные JSONP изменения

я могу обойти эту проблему с TRY/поймать, но я предпочел бы не использовать этот метод, когда я знаю, в чем проблема:

try { 
    buildHTML.push("<tr><td>" + day.td[0].div.abbr.content + "</td><td><img src='" + day.td[1].div.div.img.src + "' /></td><td>" + day.td[2].span[0].span.content + "</td><td>" + day.td[3].span[0].span.content + "</td><td>" + day.td[4].span[0].span[1].content + "</td>"); 
} catch(err) { 
    buildHTML.push("<tr><td>" + day.td[0].div.abbr.content + "</td><td><img src='" + day.td[1].div.div.img.src + "' /></td><td></td><td>" + day.td[3].span[0].span.content + "</td><td>" + day.td[4].span[0].span[1].content + "</td>"); 
} 

ORIGINAL ВОПРОС:

Используя следующую JSONP службу:

http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%20%3D%20%22http%3A%2F%2Fnews.bbc.co.uk%2Fweather%2Fforecast%2F4276%3F%26search%3Dgerrards%2520cross%26itemsPerPage%3D10%26region%3Dworld%26area%3DGerrards%2520Cross%22%20and%20xpath%3D'%2F%2Ftbody'&format=json&callback=cbfunc22

Я использую следующий скрипт для захвата данных:

$(document).ready(function() { 
    get_bbc_weather(); 

    function get_bbc_weather() { 
     $.ajax({ 
      url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%20%3D%20%22http%3A%2F%2Fnews.bbc.co.uk%2Fweather%2Fforecast%2F4276%3F%26search%3Dgerrards%2520cross%26itemsPerPage%3D10%26region%3Dworld%26area%3DGerrards%2520Cross%22%20and%20xpath%3D'%2F%2Ftbody'&format=json&callback=cbfunc22&rand=" + Math.random(), 
      type: 'GET', 
      dataType: 'jsonp', 
      jsonp: 'callback', 
      jsonpCallback: 'cbfunc22', 
      error: function(xhr, status, error) { 
       alert(xhr.responseText); 
      }, 
      success: function(data) { 
       var buildHTML = []; 

       var weather = data.query.results.tbody.tr; 

       buildHTML.push("<tr><td>Day</td><td>Weather</td><td>Max<br />Day<br />(°C)</td><td>Min<br />Night<br />(°C)</td><td>Wind<br />(MPH)</td>"); 

       for (var i = 0; i < weather.length; i++) { 
        var day = weather[i]; 

        buildHTML.push("<tr><td>" + day.td[0].div.abbr.content + "</td><td><img src='" + day.td[1].div.div.img.src + "' /></td><td>" + day.td[2].span[0].span.content + "</td><td>" + day.td[3].span[0].span.content + "</td><td>" + day.td[4].span[0].span[1].content + "</td>"); 
       } 

       $('#divContent1').empty().append("<table>" + buildHTML.join("</tr>") + "</table>") 


      } 
     }); 

    } 

}); 

Однако в определенное время суток, day.td[2].span[0].span.content становится null. Когда это произойдет, как его обнаружить и использовать следующий раздел temp min вместо этого только в первый день? Остальные дни должны продолжать использовать раздел temp max.

+0

Ответ на этот вопрос ниже ответа. Если нет, есть ли лучший ответ? – oshirowanen

+0

Код в 'try ... catch' заменяет пустое значение пустым значением. Это то, что вы хотите, или вы хотите какую-то другую ценность, как объяснялось в вопросе? Если это так, в разделе «следующий временный раздел», что означает «следующий» и «раздел»? – Guffa

+0

Как вы пришли к выводу, что «' day.td [2] .span [0] .span.content' становится 'null'?? Это утверждение, по-видимому, вызвало половину ответов, являющихся не более чем ответами на вопрос «Как сделать довольно условным?». – mercator

ответ

5

Возможно, я заявляю здесь очевидное, но почему бы просто не использовать инструкцию if?

if (day.td[2].span[0].span.content != null) { 
    buildHTML.push("<tr><td>" + day.td[0].div.abbr.content + "</td><td><img src='" + day.td[1].div.div.img.src + "' /></td><td>" + day.td[2].span[0].span.content + "</td><td>" + day.td[3].span[0].span.content + "</td><td>" + day.td[4].span[0].span[1].content + "</td>"); 
} 
else { 
    buildHTML.push("<tr><td>" + day.td[0].div.abbr.content + "</td><td><img src='" + day.td[1].div.div.img.src + "' /></td><td></td><td>" + day.td[3].span[0].span.content + "</td><td>" + day.td[4].span[0].span[1].content + "</td>"); 
} 
+0

Очевидное легко упускается из виду. Я попробую это и дам вам знать. – oshirowanen

1

Я знаю, что это намного больше, чем вы, возможно, хотели, но я действительно решаю эту проблему.

Вместо того, чтобы возвращать JSON из веб-службы, здесь я бы рекомендовал получать HTML (example request), поскольку вы используете jQuery, и он обеспечивает хороший механизм поиска - в отличие от того, что вы сами перемещаете структуру и запускаете в нее, эта структура меняется.

Вот мой код для создания той же таблицы, которую вы делаете, в структуре-агностик. Я оставил все части ajax, так как они останутся прежними. Это просто обработчик успеха.

function success(data) { 

    var 

    $data = $('<table></table>') 
     .html(data.results[0]), 

    $table = $(
     '<table>' + 
     '<thead>' + 
      '<tr>' + 
      '<th>Day</th>' + 
      '<th>Weather</th>' + 
      '<th>Max<br />Day<br />(°C)</th>' + 
      '<th>Min<br />Night<br />(°C)</th>' + 
      '<th>Wind<br />(MPH)</th>' + 
      '</tr>' + 
     '</thead>' + 
     '<tbody></tbody>' + 
     '</table>' 
    ), 

    $tbody = $table.find('tbody'); 

    $data 
    .find('tr') 
    .each(function(index, tr){ 

     var 

     $input = $(tr), 
     $output = $('<tr></tr>') 
      .appendTo($tbody), 

     selectors = [ 
      '.slotname abbr', 
      '.summary p', 
      '.temp.max .cent', 
      '.temp.min .cent', 
      '.wind .mph' 
     ], 
     i = selectors.length, 

     text, 
     $cell; 

     while (i--) { 
     $('<td></td>') 
      .text(
      $input 
       .find(selectors[i]) 
       .text() 
     ) 
      .prependTo($output); 
     } 

    }); 

    $('#divContent1') 
    .empty() 
    .append($table); 

} 

Надеюсь, это поможет!

+0

Это, к сожалению, не является структурно-агностическим, поскольку '.temp.max .cent' не существует, когда это ночное время, поэтому вместо этого вы получаете только массив из 4 элементов и в конечном итоге помещаете данные в неправильные столбцы , – mercator

+0

Да, я думал, вы можете это сказать. Я понял, что это произойдет. Я обновил пример работы, как ожидалось. – jimbojw

1

Для использования мин темп с того же дня, изменить

day.td[2].span[0].span.content 

к этому

(day.td[2].span[0].span.content == null ? day.td[3].span[0].span.content : day.td[2].span[0].span.content) 

Если это по-прежнему бросает исключение, вы должны выяснить, какая часть day.td[2].span[0].span.content возвращается пустым, то есть, возможно, вам нужно проверить day.td[2].span[0] == null.

Редактировать: Чтобы было ясно, ваше заявление будет выглядеть следующим образом:

buildHTML.push("<tr><td>" + day.td[0].div.abbr.content + "</td><td><img src='" + day.td[1].div.div.img.src + "' /></td><td>" + (day.td[2].span[0].span.content == null ? day.td[3].span[0].span.content : day.td[2].span[0].span.content) + "</td><td>" + day.td[3].span[0].span.content + "</td><td>");

Кроме того, если вы просто хотите, чтобы ячейка быть пустым (вместо того, чтобы использовать максимальную температуру), используйте этот :

(day.td[2].span[0].span.content == null ? "" : day.td[2].span[0].span.content)

1

Вы можете использовать || opreator заменить нулевое значение с другим значением.Я не знаю точно, какое значение вы хотите, но это будет использовать значение для следующего дня:

buildHTML.push(
    "<tr>" + 
    "<td>" + day.td[0].div.abbr.content + "</td>" + 
    "<td><img src='" + day.td[1].div.div.img.src + "' /></td>" + 
    "<td>" + (day.td[2].span[0].span.content || weather[i+1].td[2].span[0].span.content) + "</td>" + 
    "<td>" + day.td[3].span[0].span.content + "</td>" + 
    "<td>" + day.td[4].span[0].span[1].content + "</td>" 
); 
1

Как уже упоминалось sJhonny, вам просто нужно использовать, если заявление. Уловка заключается в том, что вам нужно знать, что на самом деле является нулевым, потому что после указателя в любом месте после нулевого значения вы получите сообщение об ошибке. Не зная сведения о данных, которые вы получаете назад, вы просто должны быть в состоянии проверить все вниз линии:

var td2 = ""; 
if (day.td[2] != null && day.td[2].span != null && day.td[2].span.length > 0 && day.td[2].span[0] != null && day.td[2].span[0].span != null && day.td[2].span[0].span.content != null) { 
    td2 = day.td[2].span[0].span.content; 
} 

buildHTML.push("<tr><td>" + day.td[0].div.abbr.content + "</td><td><img src='" + day.td[1].div.div.img.src + "' /></td><td>" + td2 + "</td><td>" + day.td[3].span[0].span.content + "</td><td>" + day.td[4].span[0].span[1].content + "</td>"); 

Конечно, если вы знаете, что поле специально быть установлен в нуль, можно упростить, что если заявление. Я бы не стал беспокоиться об использовании try/catch, если это делает ваш код более понятным (в этом случае я думаю, что предпочитаю try/catch, сам). В любом случае вы, вероятно, должны проверять эти другие поля - вы можете защитить свой сайт от случайных ошибок во избежание того, что какое-то другое поле данных окажется нулевым в этом фиде.

2

Если вы use the YQL console to examine the output you're getting, вы увидите, что весь td станет null. Вот почему вы получаете ошибку.

Вы должны делать:

if (day.td[2] == null) 

(. Или в зависимости от того, как вы представляете себе делать условный выход)

Просто так случилось, что это было ночью в Великобритании, когда я смотрел на нее, так Я действительно получил проблематичный вывод. Но учитывая, что that page может найти вам прогноз погоды для мест по всему миру, вы можете так же легко выбрать город в какой-то другой часовой пояс и использовать его для его проверки.

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