jquery .ajax,谷歌可视化和让他们一起工作的问题

时间:2009-07-05 06:10:27

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

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

根据数据表助手维基页面上的指导,香草版本工作正常,即

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

    代码隐藏:

    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>
    

    当我尝试重构以便在PageMethod中包装数据请求以通过.ajax()调用并附加一个click事件时,事情就会崩溃。特别是,调试我可以看到.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调用,当我点击停止以停止加载页面时,我得到“$未定义,$ .ajax({”在firebug中。

    令人沮丧!

    有什么想法吗?

1 个答案:

答案 0 :(得分:2)

如果你延迟执行jQuery ready功能直到谷歌加载,jQuery和谷歌可视化将很好地一起玩。这可能不是理想的方法,但它可以解决在保证加载任何库之前调用代码的问题。

示例:

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处理程序,并根据两个库延迟执行代码,直到它们都准备就绪。