【问题标题】:Google chart not working without throwing an exception谷歌图表无法正常工作而不会引发异常
【发布时间】:2015-11-11 14:55:19
【问题描述】:

我们正在使用 AJAX 来显示用户的统计信息 - 每月(当月和过去 12 个月)发送和接收的电子邮件数量。我正在使用谷歌图表。当我在没有 AJAX 的情况下执行此操作时,它可以工作,但使用 AJAX 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 个月。

我尝试在函数drawTitleSubtitle() 中使用console.log,但它似乎根本没有被调用。但是AJAX返回结果后(第二次调用),&lt;html&gt;里面没有&lt;body&gt;

JS 小提琴 - http://jsfiddle.net/uriwise/Lpsb0tqn/

【问题讨论】:

标签: javascript jquery ajax charts google-visualization


【解决方案1】:

您所看到的行为(“drawTitleSubtitle() [...] 似乎没有被调用”)本质上是由于正在执行的操作的顺序。

因为您正在加载所需的包 (google.load(...)) 并在 $(document).ready() 中设置所需的回调 (google.setOnLoadCallback(...)),所以当包时,Google Charts API 无法引用所需的回调 (drawTitleSubtitle())最终被加载。

您应该定义drawTitleSubtitle(),加载所需的包(google.load(...))并在输入$(document).ready()之前设置所需的回调google.setOnLoadCallback(...)

$(document).ready() 内,try_ajax() 应调用drawTitleSubtitle(),同时从/ajax/user/email_statistics 传递所需的Ajax 响应。

【讨论】:

    【解决方案2】:

    最终我按照 Lee 的建议做了,并调用了 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_ajaxdraw_google_chart 总是在$(document).ready() 之后调用,之前从未调用过(因为我需要将HTML 元素放在DOM 中)。

    JS 小提琴 - http://jsfiddle.net/uriwise/tp1xhun0/

    但是,如果我在$(document).ready() 中调用google 函数,那么它不起作用,我会再次得到空白页。我没有在 Google 的网站上找到此文档:

    $(document).ready(function() {
        google.load('visualization', '1', {packages: ['corechart', 'bar']});
        google.setOnLoadCallback(try_ajax_first_time);
    });
    

    【讨论】:

      猜你喜欢
      • 2016-09-28
      • 2018-01-02
      • 2011-03-25
      • 2017-05-27
      • 1970-01-01
      • 2014-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多