2015-11-11 7 views
1

Мы используем AJAX для отображения статистики пользователя - сколько писем было отправлено и получено в месяц (в текущем месяце и предыдущих 12 месяцах). Я использую диаграммы Google. Когда я делал это без AJAX, это сработало, но с диаграммами AJAX Google не работает - вся страница становится пустой, и в консоли нет исключения. Вот мой код:График Google не работает без исключения исключения

<script type="text/javascript" src="https://www.google.com/jsapi"></script> 
<script type="text/javascript"> 
    $(document).ready(function() { 
     var params = { 
      "email": "{{ statistics_user_email }}", 
      "today_email_statistics_query_job_json": JSON.stringify({{ today_email_statistics_query_job_json|safe }}), 
      "this_month_email_statistics_query_job_json": JSON.stringify({{ this_month_email_statistics_query_job_json|safe }}), 
      "last_13_months_monthly_email_statistics_query_job_json": JSON.stringify({{ last_13_months_monthly_email_statistics_query_job_json|safe }}) 
     }; 

     function try_ajax() { 
      $.ajax({ 
       type: 'POST', 
       url: '/ajax/user/email_statistics', 
       data: params, 
       success: function(reply) { 
        if (reply.wait === true) { 
         // Try again after 4 seconds. 
         setTimeout(try_ajax, 4000); 
        } else if (reply.ready === true) { 
         function drawTitleSubtitle() { 
          var data = new google.visualization.DataTable(); 
          data.addColumn('string', 'Month'); 
          data.addColumn('number', 'Emails sent'); 
          data.addColumn('number', 'Emails received'); 

          var rows = []; 
          for (var i = 0; i < reply["last_13_months_monthly_email_statistics"].length; i++) { 
           var row = reply["last_13_months_monthly_email_statistics"][i]; 
           rows.push([row["month"], row["sent"], row["received"]]); 
          } 
          data.addRows(rows); 

          var options = { 
           'title': 'How Many Vegan Cheeseburgers I Ate Last Night', 
           'width': 400, 
           'height': 300 
          }; 

          var material = new google.charts.Bar(document.getElementById('last-13-month-chart-div')); 
          material.draw(data, options); 
         } 

         $("#today-emails-sent-span").html(reply["today_email_statistics"]["messages_sent"]); 
         $("#today-emails-received-span").html(reply["today_email_statistics"]["messages_received"]); 
         $("#this-month-emails-sent-span").html(reply["this_month_email_statistics"]["messages_sent"]); 
         $("#this-month-emails-received-span").html(reply["this_month_email_statistics"]["messages_received"]); 
         google.load('visualization', '1', {packages: ['corechart', 'bar']}); 
         google.setOnLoadCallback(drawTitleSubtitle); 
         $("#please-wait-div").addClass("hidden"); 
         $("#email-statistics-div").removeClass("hidden"); 
        } else { 
         console.error("AJAX returned unexpected results!", reply); 
        } 
       } 
      }); 
     } 

     try_ajax(); 
    }); 
</script> 

Когда я комментирую следующие строки, она работает без карты:

     google.load('visualization', '1', {packages: ['corechart', 'bar']}); 
         google.setOnLoadCallback(drawTitleSubtitle); 

на основе AJAX вернулся этот объект один раз:

{"wait": true} 

И во второй раз :

{"ready": true, "last_13_months_monthly_email_statistics": [{"received": 23, "sent": 2, "month": "2015-10"}, {"received": 15, "sent": 4, "month": "2015-11"}], "this_month_email_statistics": {"messages_received": 15, "messages_sent": 4}, "today_email_statistics": {"messages_received": 0, "messages_sent": 1}} 

Я не включая HTML, но все элементы существуют на странице. Все работает, кроме графика, который работал раньше, когда я не использовал AJAX. В чем проблема?

Кстати, я только загрузил данные за этот месяц и в предыдущий месяц, это не ошибка. В будущем мы можем показать предыдущие 12 месяцев.

Я попытался использовать console.log в функции drawTitleSubtitle(), но, похоже, он вообще не называется. Но нет <body> внутри <html> после того, как AJAX возвращает результат (второй раз он называется).

JS скрипка - http://jsfiddle.net/uriwise/Lpsb0tqn/

+1

Может быть, Google не любит веганский чизбургеры :) –

+2

@ T3H40 Это была пицца (скопировано из https://google-developers.appspot.com/chart/interactive/docs/quick_start), и я изменил его ... :-) – Uri

+1

Там вы идете! Проблема решена, исправлена ​​и закрыта. –

ответ

1

поведение вы свидетели («drawTitleSubtitle() [...], похоже, не будет называться»), по существу, из-за того, какую операцию выполняются.

Поскольку вы загружаете нужные пакеты (google.load(...)) и установки нужного обратного вызова (google.setOnLoadCallback(...)) в $(document).ready(), то графики API Google не может ссылаться на нужную функцию обратного вызова (drawTitleSubtitle()), когда пакеты в конце концов загружены.

Вы должны определить drawTitleSubtitle(), загрузить нужные пакеты (google.load(...)) и установить желаемый обратный вызов google.setOnLoadCallback(...) перед входом $(document).ready().

В пределах $(document).ready(), try_ajax() следует затем вызывать drawTitleSubtitle() при прохождении в требуемом ответе Ajax от /ajax/user/email_statistics.

0

В конце концов я сделал то, что предложил Ли, и назвал функции google, не дожидаясь $(document).ready(). Вот мой код:

Редактировать: Я разделил свой код на 3 отдельные функции и передал параметры при их вызове.

<script type="text/javascript" src="https://www.google.com/jsapi"></script> 
<script type="text/javascript"> 
    function draw_google_chart(ajax_reply) { 
     var data = new google.visualization.DataTable(); 
     data.addColumn('string', 'Month'); 
     data.addColumn('number', 'Emails sent'); 
     data.addColumn('number', 'Emails received'); 

     var rows = []; 
     for (var i = 0; i < ajax_reply["last_13_months_monthly_email_statistics"].length; i++) { 
      var row = ajax_reply["last_13_months_monthly_email_statistics"][i]; 
      rows.push([row["month"], row["sent"], row["received"]]); 
     } 
     data.addRows(rows); 

     var options = { 
      'title': 'How Many Vegan Cheeseburgers I Ate Last Night', 
      'width': 400, 
      'height': 300 
     }; 

     var material = new google.charts.Bar(document.getElementById('last-13-month-chart-div')); 
     material.draw(data, options); 
    } 

    function try_ajax(ajax_params) { 
     $.ajax({ 
      type: 'POST', 
      url: '/ajax/user/email_statistics', 
      data: ajax_params, 
      success: function(ajax_reply) { 
       if (ajax_reply.wait === true) { 
        // Try again after 4 seconds. 
        setTimeout(function() { 
         try_ajax(ajax_params); 
        }, 4000); 
       } else if (ajax_reply.ready === true) { 
        $("#today-emails-sent-span").html(ajax_reply["today_email_statistics"]["messages_sent"]); 
        $("#today-emails-received-span").html(ajax_reply["today_email_statistics"]["messages_received"]); 
        $("#this-month-emails-sent-span").html(ajax_reply["this_month_email_statistics"]["messages_sent"]); 
        $("#this-month-emails-received-span").html(ajax_reply["this_month_email_statistics"]["messages_received"]); 
        draw_google_chart(ajax_reply); 
        $("#please-wait-div").addClass("hidden"); 
        $("#email-statistics-div").removeClass("hidden"); 
       } else { 
        console.error("AJAX returned unexpected results!", ajax_reply); 
       } 
      } 
     }); 
    } 

    function try_ajax_first_time() { 
     $(document).ready(function() { 
      var ajax_params = { 
       "email": "{{ statistics_user_email }}", 
       "today_email_statistics_query_job_json": JSON.stringify({{ today_email_statistics_query_job_json|safe }}), 
       "this_month_email_statistics_query_job_json": JSON.stringify({{ this_month_email_statistics_query_job_json|safe }}), 
       "last_13_months_monthly_email_statistics_query_job_json": JSON.stringify({{ last_13_months_monthly_email_statistics_query_job_json|safe }}) 
      }; 

      try_ajax(ajax_params); 
     }); 
    } 

    google.load('visualization', '1', {packages: ['corechart', 'bar']}); 
    google.setOnLoadCallback(try_ajax_first_time); 
</script> 

Пожалуйста, обратите внимание, что функции try_ajax и draw_google_chart всегда вызываются после $(document).ready(), никогда раньше (потому что мне нужно HTML-элементы, чтобы быть в DOM).

JS скрипка - http://jsfiddle.net/uriwise/tp1xhun0/

Однако, если я называю google функции в $(document).ready() тогда она не работает, я получаю пустую страницу. Я не нашел это документировано на сайте Google:

$(document).ready(function() { 
    google.load('visualization', '1', {packages: ['corechart', 'bar']}); 
    google.setOnLoadCallback(try_ajax_first_time); 
}); 
Смежные вопросы