【问题标题】:jquery .ajax, google visualisation and problems getting them to work togetherjquery .ajax、谷歌可视化和让它们一起工作的问题
【发布时间】:2009-07-05 06:10:27
【问题描述】:

我正在尝试同时使用 jquery 的 .ajax()、google 可视化注释时间轴和 one of the google datatable helpers。最终我想要的是在页面上有一个链接,当用户点击它时,数据通过 jquery.ajax() 异步加载,返回为符合谷歌可视化的 JSON 并传递给图表 API 以生成带注释的时间线。

按照 datatable helper wiki 页面上的指南,原版版本运行良好,即

  1. 没有 ajax 加载数据(而是通过调用 Page_Load() 代码后面的方法中的 Page.ClientScript.RegisterStartupScript() 将 json 数据注入页面)和
  2. 没有与页面上的链接关联的点击事件

这是原版的工作代码:

代码隐藏:

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        DataTable dt = PopulateDatatable();
        ConvertToGoogleDatatable(dt);
    }

    private void ConvertToGoogleDatatable(DataTable dt)
    {
        // Use of Bortosky helper class to generated 
        // google visualisation compliant json
        GoogleDataTable gdt = new GoogleDataTable(dt);
        using (MemoryStream memoryStream = new MemoryStream())
        {
            gdt.WriteJson(memoryStream);
            memoryStream.Position = 0;
            StreamReader sr = new StreamReader(memoryStream);
            Page.ClientScript.RegisterStartupScript(this.GetType(), "vis", string.Format("var jsonData = {0}", sr.ReadToEnd()), true);
        }
    }

    private DataTable PopulateDatatable()
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("Date", typeof(System.DateTime));
        dt.Columns.Add("High", typeof(System.Double));
        dt.Columns.Add("Low", typeof(System.Double));
        dt.Columns.Add("Closing Price", typeof(System.Double));

        using (StreamReader sr = new StreamReader(@"data.csv"))
        {
            string line;
            line = sr.ReadLine();

            while ((line = sr.ReadLine()) != null)
            {
                string[] lineParts = line.Split(',');
                dt.Rows.Add(new object[] { Convert.ToDateTime(lineParts[0]), lineParts[2], lineParts[3], lineParts[4] });
            }
        }
        return dt;
    }
}

XHTML:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GoogleVis._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<script type='text/javascript' src='http://www.google.com/jsapi'></script>
<script type='text/javascript'>

    google.load('visualization', '1', {'packages':['annotatedtimeline']});
    google.setOnLoadCallback(drawChart);

    function drawChart() {
    var data = new google.visualization.DataTable(jsonData, 0.5);
    var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
    chart.draw(data, {displayAnnotations: true});
    }

</script>
<title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
     <div id='chart_div' style='width: 90%; height: 500px;'></div>
    </div>
    </form>
</body>
</html>

当我尝试重构以便将数据请求包装在要通过 .ajax() 调用的 PageMethod 中并附加单击事件时,事情就崩溃了。特别是,调试我可以看到 .ajax() 调用工作正常,并且正在返回 json 数据。 json 数据也已正确传递给 drawChart() 方法,但执行不会超出此行:

var data = new google.visualization.DataTable(msg.d, 0.5);

浏览器只是停留在说“正在从 google.com 传输数据...”

这是无效的代码:

代码隐藏:

public partial class _Default : System.Web.UI.Page
{
    [WebMethod]
    public static string AjaxMethod()
    {
        DataTable dt = PopulateDatatable();
        return ConvertToGoogleDatatable(dt);
    }

    private static string ConvertToGoogleDatatable(DataTable dt)
    {
        GoogleDataTable gdt = new GoogleDataTable(dt);
        using (MemoryStream memoryStream = new MemoryStream())
        {
            gdt.WriteJson(memoryStream);
            memoryStream.Position = 0;
            StreamReader sr = new StreamReader(memoryStream);
            // FOLLOWING 3 LINES DIFFERENT FROM VANILLA VERSION ABOVE!
            string returnValue = sr.ReadToEnd();
            sr.Close();
            return returnValue;
        }
    }

    private static DataTable PopulateDatatable()
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("Date", typeof(System.DateTime));
        dt.Columns.Add("High", typeof(System.Double));
        dt.Columns.Add("Low", typeof(System.Double));
        dt.Columns.Add("Closing Price", typeof(System.Double));

        using (StreamReader sr = new StreamReader(@"data.csv"))
        {
            string line;
            line = sr.ReadLine();

            while ((line = sr.ReadLine()) != null)
            {
                string[] lineParts = line.Split(',');
                dt.Rows.Add(new object[] { Convert.ToDateTime(lineParts[0]), lineParts[2], lineParts[3], lineParts[4] });
            }
        }
        return dt;
    }
}

XHTML:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GoogleVis._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<script type='text/javascript' src='http://www.google.com/jsapi'></script>
<script type='text/javascript' src="jquery-1.3.2.min.js"></script>
<script type='text/javascript'>

    $(document).ready(function() {
        $("#Result").click(function() {
            $.ajax({
                type: "POST",
                url: "Default.aspx/AjaxMethod",
                data: "{}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function(msg) {
                    google.load('visualization', '1', {'packages':['annotatedtimeline']});
                    google.setOnLoadCallback(drawChart(msg));
                }
            });
        });
    });

    function drawChart(msg) {
        var data = new google.visualization.DataTable(msg.d, 0.5);
        var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
        chart.draw(data, {displayAnnotations: true});
    }

</script>
<title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <div id="Result"><a href="#">Load!</a></div>
     <div id='chart_div' style='width: 90%; height: 500px;'></div>
    </div>
    </form>
</body>
</html>

我还发现剥离大部分功能并通过将其包装在 $(document).ready(function() {} 中来修改 vanilla 工作版本 javascript(如下所示)具有相同的破坏性效果。

<script type='text/javascript'>
    $(document).ready(function() {

        google.load('visualization', '1', {'packages':['annotatedtimeline']});
        google.setOnLoadCallback(drawChart);

        function drawChart() {
        var data = new google.visualization.DataTable(jsonData, 0.5);
        var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
        chart.draw(data, {displayAnnotations: true});
        }
    }
</script>

所以...关于我应该如何将这些调用链接在一起以使其工作的任何想法?

谢谢

编辑:

以下代码重新排列似乎也不起作用 - 特别是 LoadData() 中的警报消息永远不会显示!

$(document).ready(function() {
  $("#Result").click(function() {
        google.load('visualization', '1', {'packages':['annotatedtimeline']});
        google.setOnLoadCallback(LoadData)
  });
});

function LoadData(){
    alert("breakpoint");
    $.ajax({
      type: "POST",
      url: "Default.aspx/AjaxMethod",
      data: "{}",
      contentType: "application/json; charset=utf-8",
      dataType: "json",
      success: function(msg) {
            var jsonData = msg.d;

            var data = new google.visualization.DataTable(jsonData, 0.5);
            var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
            chart.draw(data, {displayAnnotations: true});
      }
    });
};

编辑 2:

又一个不起作用的变体!!!

以下结果导致数据被加载(即 .ajax() 调用有效),但随后我从 google javascript 收到 this.t undefined 错误。

<script type='text/javascript' src="jquery-1.3.2.min.js"></script>
<script type='text/javascript'>

    google.load('visualization', '1', {'packages':['annotatedtimeline']});
    google.setOnLoadCallback(LoadData);

    function LoadData() {
        $.ajax({
            type: "POST",
            url: "Default.aspx/AjaxMethod",
            data: "{}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(msg) {
                var data = new google.visualization.DataTable(msg.d, 0.5);
                var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
                chart.draw(data, {displayAnnotations: true});
            }
        });
    }

</script>

将以上内容包装在 $(document).ready(function() {});让我回到之前的“从 google.com 传输数据”,它就在那里。没有进行 ajax 调用,当我点击停止以停止加载页面时,我得到 "$ is not defined, $.ajax({" in firebug.

令人沮丧!

有什么想法吗?

【问题讨论】:

    标签: asp.net asp.net-ajax jquery


    【解决方案1】:

    如果您延迟执行 jQuery 就绪函数直到 google 加载,jQuery 和 Google Visualizations 将很好地协同工作。这可能不是理想的方法,但它可以解决在保证加载之前调用任一库中的代码的问题。

    例子:

    google.load('visualization','1',{packages:['piechart']);
    function loaded() {
      if (MyLibrary.googleLoaded) {
        MyLibrary.googleLoaded();
      } else {
        setTimeout(loaded, 50);
      }
    }
    google.setOnLoadCallback(loaded);
    

    和:

    $(document).ready(function() {
      MyLibrary.googleLoaded = function() {
        // whatever you would have put in $(document).ready();
      };
    });
    

    ...允许两个库独立绑定其 onLoad 处理程序,并根据两个库延迟执行代码,直到它们都准备好。

    【讨论】:

      猜你喜欢
      • 2012-04-22
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      • 2013-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多