【问题标题】:Unable to pass value from C# to amcharts JavaScript function无法将值从 C# 传递到 amcharts JavaScript 函数
【发布时间】:2019-04-25 04:58:37
【问题描述】:

我在 amCharts 的帮助下创建了一个图表,显示了他们网站上示例中的温度。图表显示正确。

现在我使用 C# 从数据库中获取温度,并尝试将值传递给温度被硬编码的函数,因此我得到动态值。但是,我刚拿到图表,指针仍为 0,不显示温度。

到目前为止,我已经尝试了 3 种方法:

  1. 我使用了隐藏字段,将值分配给 C# 中的隐藏字段并调用显示图表的 JavaScript 函数。它只显示图表。针头没有变化。
  2. 我使用了脚本管理器和Web API,(我不知道Web API,只是在互联网上使用过代码),结果相同,但是c#中的函数不断被调用。

  3. 我将整个 amCharts 代码放在一个 JavaScript 函数中。我在 c# 中得到了值,然后使用了

    String script = "window.onload = function() { UpdateTemp('" + dt.Rows[0][0].ToString()+ "'); };";
    ClientScript.RegisterStartupScript(this.GetType(), "UpdateTemp", script, true);
    

    再次显示相同的结果,地图显示针停留在 0。

这是我的第三种方法的代码:

ASPX 页面、JavaScript 函数

<script>
 function UpdateTemp(temp) {

     am4core.ready(function() {

            // Themes begin
            am4core.useTheme(am4themes_animated);
            // Themes end

            // create chart
            var chart = am4core.create("chartdiv", am4charts.GaugeChart);
            chart.hiddenState.properties.opacity = 0; // this makes initial fade in effect

            chart.innerRadius = -25;

            var axis = chart.xAxes.push(new am4charts.ValueAxis());
            axis.min = 0;
            axis.max = 100;
            axis.strictMinMax = true;
            axis.renderer.grid.template.stroke = new am4core.InterfaceColorSet().getFor("background");
            axis.renderer.grid.template.strokeOpacity = 0.3;

            var colorSet = new am4core.ColorSet();

            var range0 = axis.axisRanges.create();
            range0.value = 0;
            range0.endValue = 50;
            range0.axisFill.fillOpacity = 1;
            range0.axisFill.fill = colorSet.getIndex(0);
            range0.axisFill.zIndex = - 1;

            var range1 = axis.axisRanges.create();
            range1.value = 50;
            range1.endValue = 80;
            range1.axisFill.fillOpacity = 1;
            range1.axisFill.fill = colorSet.getIndex(2);
            range1.axisFill.zIndex = -1;

            var range2 = axis.axisRanges.create();
            range2.value = 80;
            range2.endValue = 100;
            range2.axisFill.fillOpacity = 1;
            range2.axisFill.fill = colorSet.getIndex(4);
            range2.axisFill.zIndex = -1;

            var hand = chart.hands.push(new am4charts.ClockHand());

            // using chart.setTimeout method as the timeout will be disposed together with a chart

            chart.setTimeout(randomValue, 2000);

            function randomValue(temp) {
                hand.showValue(temp, 1000, am4core.ease.cubicOut);
                chart.setTimeout(randomValue, 2000);
            }



        }); // end am4core.ready()

    };
</script>

C#函数获取温度并调用JavaScript函数

public void BindGrid(String charttype)
{

    string constring = "Data Source=********.DOMAIN.ORG01;Initial Catalog=Temperature;Integrated Security=SSPI;";
    using (SqlConnection con = new SqlConnection(constring))
    {
        using (SqlCommand cmd = new SqlCommand("SELECT Temperature,HighestPoint,LowestPoint FROM Temperature", con))
        {
            cmd.CommandType = CommandType.Text;
            con.Open();
            DataTable dt = new DataTable();
            dt.Load(cmd.ExecuteReader());
            temp1.Value = dt.Rows[0][0].ToString();
            con.Close();
            String script = "window.onload = function() { UpdateTemp('" + dt.Rows[0][0].ToString()+ "'); };";
             ClientScript.RegisterStartupScript(this.GetType(), "UpdateTemp", script, true);

        }
    }
}

【问题讨论】:

  • 如果您将其添加为方法“UpdateTemp”的第一条指令:“console.log(temp);”然后用浏览器打开开发工具(例如:按 F12 的 Chrome),您在控制台中看到了什么?
  • 嗨,Aliz,这是我在控制台中得到的
  • 它在哪里?您是否忘记更新您的帖子或将结果粘贴到您的评论中?
  • ScriptResource.axd?d=D9drwtSJ4hBA6O 未捕获的 Sys.ParameterCountException:Sys.ParameterCountException:Function.Error$create [as create] 处的参数计数不匹配 (localhost:61681/ScriptResource.axd?d=D
  • 我想到的基本问题,你确定你的表“温度”已经填满了吗?我看到你直接访问数据行而不检查结果是否可能为空,这很危险。

标签: javascript c# amcharts gauge


【解决方案1】:

应该修改质量代码,但我设法使它工作。 我做了 2 处更改:

  • 1:我使用了“PageLoad”方法而不是“BindGrid”(你真的需要这个吗?)
  • 2:我将原始温度值直接填充为参数(因为它是我这边的浮点数),你用简单的引号将你的数据行值包含在你的数据行值中,这被 javascript 和方法“showValue”从“hand”解释为字符串"似乎无法容忍。

代码:

结果:

一些改进代码的想法:

  • 将您的连接字符串放入配置文件中(永远不要在代码中!)
  • 如果您使用“using”,则调用资源的“close”方法无关紧要,它会自动调用它。 (在使用它的背后实际上是一个try-catch-finally,无论如何都会在finally中调用close;))
  • 如果可能的话,将数据访问与呈现页面分开,创建一个单独的类来管理它,这将提高代码的可读性和演变。
  • 如果不使用变量“temp1”,只需将其删除。
  • 当您获取数据时(无论来源如何,可能是 Web 服务或数据库或其他),在访问它并记录它之前检查 总是 是否为空,它不会花费很多并且避免异常升级。
  • 我们在 2019 年,您可以使用 Dapper 从您的查询中直接获取对象,而不是通用数据行。 (如果有兴趣,请查看网站,他们有很多有趣的教程)。

氪, 阿里

【讨论】:

  • 我认为“在访问之前检查它是否为空”是个坏建议。您应该知道您的数据有哪些可能的响应。如果可能为 null,请处理它。如果不可能,就让事情快速失败。这样您就可以立即看到并解决问题。
  • “让事情快速失败。”。我不同意,如果您的网站是活动的并且您尝试访问一个不应该为空的变量并且它是,会发生什么?您向最终用户显示堆栈错误等关键信息?我认为正确的方法是在本地管理它,用有意义的信息(异常数据和可能通过字符串的更多上下文)记录它,并抛出一个特定的异常,允许您使用适当的操作(显示弹出窗口、重定向、重定向日志,等等...),最重要的是,尽快了解问题以便能够快速修复它
  • 如果生产网站出现故障,正确的做法是记录异常并向最终用户显示 500。如果你愿意,你可以制作一个漂亮的 500 页。但是你让异常冒泡。尝试对“以防万一”进行空检查会隐藏很多问题,并很快使您的代码几乎无法维护
  • 这是一个有趣的话题,我找到了一个关于这个问题的话题(肯定还有更多):softwareengineering.stackexchange.com/questions/293328/… 这个问题似乎没有明确的答案,我仍然建议这样做大大地。 (它多次为我节省了很多时间......)
  • 谢谢你,它现在正在工作。我会根据你提到的质量进行更改。
猜你喜欢
  • 2019-11-24
  • 2015-09-19
  • 2012-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-07
  • 2016-10-10
  • 2023-03-31
相关资源
最近更新 更多