How to write clean code using Javascript and Razor

I am programming an ASP.Net MVC page and I am using data from the server to create a Google chart. The x axis is the date. The y-axis is the meaning. For comparison, 2 rows of data are built. Here is the relevant code:

@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> 

First of all, this code really works. Creating arr2 in this way turns the Razor model into something I can use. However, my nose is talking about the smell of code. It says that merging the two razor and Javascript languages, which have somewhat similar syntax for the C-based programming thread, can confuse the next person who comes in and tries to read it.

Is there a better way to write this?

+4
source share
1 answer

However, my nose is talking about the smell of code.

Oh yes, it stinks, I feel it.

Is there a better way to write this?

Sure. Never create JSON manually, as you did, mixing 2 languages ​​and writing loops and stuff. Use the JSON serializer:

 @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> 

This will create equivalent code markup like yours, but all the manipulations and coding of the model are done on the server. You can also write your own HTML helper to simplify the code:

 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 }) ) ) ); } } 

and then, in your opinion:

 @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> 
+3
source

All Articles