4

我正在编写一个 ASP.Net MVC 页面,并且我正在使用来自服务器的数据来创建一个 Google 图表。x 轴是日期。y 轴是值。绘制了 2 行数据进行比较。以下是相关代码:

@model IEnumerable<Tuple<DateTime,int,int>>


<div id="chart_div_2" style="width: 900px; height: 500px;"></div>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
    google.load("visualization", "1", { packages: ["corechart"] });
    google.setOnLoadCallback(drawChart);
    function drawChart() {

        var arr = [['Year', 'Sales', 'Expenses']];

        //Using the Razor Model to create a Javascript array.
        var arr2 = [
            @foreach(var row in Model)
            {
                @:["@row.Item1.ToString("MMM d")", @row.Item2, @row.Item3],
            }
        ];

        for (var i = 0; i < arr2.length; i++)
        {
            arr.push(arr2[i]);
        }

      var data = google.visualization.arrayToDataTable(arr);
      var chart = new google.visualization.LineChart(document.getElementById('chart_div_2'));
      chart.draw(data);

    }
</script>

首先,这段代码确实有效。以这种方式创建 arr2 确实会将 Razor 模型变成我可以使用的东西。但是,我的鼻子说代码气味。它说,将两种语言 razor 和 Javascript 放在一起,它们具有一些类似的基于 C 的编程流语法,可能会让下一个出现并尝试阅读它的人感到困惑。

有没有更好的方法来写这个?

4

1 回答 1

3

但是,我的鼻子说代码气味。

哦,是的,它很臭,我能感觉到。

有没有更好的方法来写这个?

当然。永远不要像混合两种语言并编写循环和东西那样手动构建 JSON。使用 JSON 序列化器:

@model IEnumerable<Tuple<DateTime,int,int>>

<div id="chart_div_2" style="width: 900px; height: 500px;"></div>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
    google.load("visualization", "1", { packages: ["corechart"] });
    google.setOnLoadCallback(drawChart);
    function drawChart() {
        var arr = @Html.Raw(
            Json.Encode(
                new object[] { new[] { "Year", "Sales", "Expenses" } }
                .Concat(
                    Model.Select(x => new object[] 
                    { 
                        x.Item1.ToString("MMM d"), 
                        x.Item2, 
                        x.Item3
                    })
                )
            )
        );

        var data = google.visualization.arrayToDataTable(arr);
        var chart = new google.visualization.LineChart(document.getElementById('chart_div_2'));
        chart.draw(data);
    }
</script>

这将生成与您相​​同的代码标记,但整个模型操作和编码是在服务器上完成的。您还可以编写自定义 HTML 帮助程序以将代码简化为:

public static class ChartExtensions
{
    public static IHtmlString ToChartData(
        this IEnumerable<Tuple<DateTime, int, int>> model, 
        params string[] titles
    )
    {
        return new HtmlString(
            Json.Encode(
                new object[] { titles }
                .Concat(
                    model.Select(x => new object[] 
                    { 
                        x.Item1.ToString("MMM d"), 
                        x.Item2, 
                        x.Item3 
                    })
                )
            )
        );
    }
}

然后在你看来:

@model IEnumerable<Tuple<DateTime,int,int>>

<div id="chart_div_2" style="width: 900px; height: 500px;"></div>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
    google.load("visualization", "1", { packages: ["corechart"] });
    google.setOnLoadCallback(drawChart);
    function drawChart() {
        var arr = @Model.ToChartData("Year", "Sales", "Expenses");
        var data = google.visualization.arrayToDataTable(arr);
        var chart = new google.visualization.LineChart(document.getElementById('chart_div_2'));
        chart.draw(data);
    }
</script>
于 2012-08-27T06:16:03.580 回答