0

我与谷歌从图表API一些图表一个用户控件。Asp.net渲染控制 - > JavaScript错误

当用户控件得到装载和通常的方式一切正常的服务器渲染。但是,当我使用AJAX的web服务的渲染控制异步和使用Ajax返回的HTML,并将其添加到页面中,我得到一些脚本错误的萤火(铬称其为的ReferenceError):

“谷歌不是定义”

IMAGE

我的项目是与一些JavaScript ASP.Net MVP Web表单。
我已经在那里我已经重新发出一个样本项目。 Download it here

控制渲染器的代码:

public virtual string RenderControlToString(string path, bool htmlEncode) 
{ 
    StringWriter stringWriter = new StringWriter(); 
    this.RenderControl(path, (TextWriter)stringWriter); 
    string s = stringWriter.ToString(); 
    if (!htmlEncode) 
     return s; 
    else 
     return HttpContext.Current.Server.HtmlEncode(s); 
} 

public virtual void RenderControl(string path, TextWriter writer) 
{ 
    var page = new PageForRendering(); 
    page.Controls.Add(page.LoadControl(path)); 
    HttpContext.Current.Server.Execute((IHttpHandler)page, writer, true); 
} 

(要省略“需要在形式”错误 - 有页面上的形式中,控制被添加到)

public class PageForRendering : Page 
{ 
    public override void VerifyRenderingInServerForm(Control control) 
    {} 
} 

脚本上该用户控件:

<script type="text/javascript" src="https://www.google.com/jsapi"></script> 
<script type="text/javascript"> 
    console.log("Loading Google Charts..."); 
    google.load('visualization', '1.0', { 'packages': ['corechart'] }); 
    console.log("Google Charts loaded!"); 

    google.setOnLoadCallback(function() { 
     ...some code... 
    }); 
</script> 

使用Firebug我发现https://www.google.com/jsapi加载罚款,但只有第一个我的控制台日志已打印。

我想这可能是某种范围的问题...... 的谷歌变量将在此脚本中定义:

<script type="text/javascript" src="https://www.google.com/jsapi"></script> 

但在这种情况下,在接下来的脚本块访问。正常的渲染它正常工作。无论是在google.load调用之前加载脚本,还是由于不同的呈现方法,google变量现在以某种方式在另一个范围内定义。

如果我看的萤火DOM谷歌的变量的定义如下here。但是我发现,如果我将一个断点放在一行:google.load('visualization', '1.0', { 'packages': ['corechart'] });,我发现在这个时候,google变量没有在DOM中定义。所以加载脚本可能也是一些问题。但行<script type="text/javascript" src="https://www.google.com/jsapi"></script>是在它之前,它应该同步执行权?当我在萤火虫中检查网络时,我也发现该文件已正确下载。

我可能还需要提及的是,用户控件加载AJAX代码如下所示:

<div id="statisticsContent">&nbsp;</div> 

<script type="text/javascript"> 
    $(document).ready(function() { 
     function getStatisticsView() { 
      var id = $(".chooseStatisticsToShow input:radio:checked").val(); 
      var statisticsType = (id == $(".choosePlayingGroupDropDownList option:selected").val() ? 1 : 0); 

      $.ajax({ 
       cache: false, 
       global: false, 
       type: "POST", 
       contentType: "application/json; charset=utf-8", 
       dataType: "json", 
       url: '/Services/StatisticsService.svc/GetStatisticsView', 
       data: JSON.stringify({ 
        statisticsType: statisticsType, 
        id: id 
       }), 
       success: function (data) { 
         $("#statisticsContent").html(data.d.ViewHtml); 
       } 
      }); 
     } 
     getStatisticsView(); 

     $(".chooseStatisticsToShow").change(function() { 
      getStatisticsView(); 
     }); 
    }); 
</script> 



我已经在那里我已经重新发出一个样本项目。 Download it here

回答

1

在您的服务发送响应并且您使用$("#statisticsContent").html(data.d.ViewHtml);添加了它之后,浏览器会解释html并开始加载并执行脚本。我怎么知道它?刚刚经历 - 在我的项目每次我试图注入<script src='...'>浏览器时没有等待脚本加载和未来script变量与自定义代码被立即执行。

这是你的情况,你需要等待jsapi加载,然后才执行代码来加载包并执行图表渲染。下面是代码:

<div id="chart_div"></div> 

<script type="text/javascript" src="https://www.google.com/jsapi"></script> 
<script type="text/javascript"> 
    waitForGoogleApiAndLoadPackages(); 
    function waitForGoogleApiAndLoadPackages() { 
     if (typeof (google) === 'undefined') 
      setTimeout(waitForGoogleApiAndLoadPackages, 100); 
     else { 
      google.load('visualization', '1.0', { 'callback': 'renderChart', 'packages': ['corechart'] }); 
     } 
    } 

    function renderChart() { 
     var data = new google.visualization.DataTable(); 
     data.addColumn('string', 'Topping'); 
     data.addColumn('number', 'Slices'); 
     data.addRows([['Mushrooms', 3], ['Onions', 1], ['Olives', 1], ['Zucchini', 1], ['Pepperoni', 2]]); 

     var options = { 'title': 'How Much Pizza I Ate Last Night', 'width': 400, 'height': 300 }; 

     var chart = new google.visualization.PieChart(document.getElementById('chart_div')); 
     chart.draw(data, options); 
    } 
</script> 

另一个有趣的部分是在waitForGoogleApiAndLoadPackages功能else块。这是解决Why does google.load cause my page to go blank?问题中描述的问题的解决方法。


Why does google.load cause my page to go blank?报价:

看起来像的google.load使用 document.write()的,这要是在页面加载后使用添加脚本到页面,抹了 HTML。

+0

听起来不错..我会看看它,当我得到时间和报告回来。 waitForGoogleApiToLoad == waitForGoogleApiAndLoadPackages对不对? – 2013-04-25 21:03:44

+0

@MortenHolmgaard是的,你是对的,这是功能名称中的错字。 – 2013-04-26 07:26:33

+0

我工作!非常感谢你 - 我有这么长时间的问题.. – 2013-04-26 07:59:40