【发布时间】:2009-07-05 06:10:27
【问题描述】:
我正在尝试同时使用 jquery 的 .ajax()、google 可视化注释时间轴和 one of the google datatable helpers。最终我想要的是在页面上有一个链接,当用户点击它时,数据通过 jquery.ajax() 异步加载,返回为符合谷歌可视化的 JSON 并传递给图表 API 以生成带注释的时间线。
按照 datatable helper wiki 页面上的指南,原版版本运行良好,即
- 没有 ajax 加载数据(而是通过调用 Page_Load() 代码后面的方法中的 Page.ClientScript.RegisterStartupScript() 将 json 数据注入页面)和
- 没有与页面上的链接关联的点击事件
这是原版的工作代码:
代码隐藏:
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