I'm creating a Google Maps partial view/user control in my project that is passed a strongly typed list of objects containing latitude and longitude values.
Currently, this is the code I have for the partial:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Project.Models.Entities.Location>>" %>
<!-- Place for google to put the map -->
<div id="report_map_canvas" style="width: 100%; height: 728px; margin-bottom: 2px;">
</div>
<script type='text/javascript'>
google.load("maps", "2");
$(document).ready(initializeMap);
function initializeMap() {
if (开发者_如何学JAVAGBrowserIsCompatible()) {
var map = new GMap2(document.getElementById('report_map_canvas'));
map.setCenter(new GLatLng(51.5, -0.1167), 2);
<% foreach (var item in Model) { %>
map.addOverlay(new GMarker(new GLatLng('<%= Html.Encode(item.latitude)%>','<%= Html.Encode(item.longitude)%>'),{ title: '<%= Html.Encode(String.Format("{0:F}",item.speed)) %> km/h '}));
<% } %>
map.setUIToDefault();
}
}
</script>
Is it right to dynamically create the javascript file this way by looping over the list and emitting javascript?
Is there a better way to do it?
i don't prefer this way because if you have many items to add you will make a big document to load for the user. instead I prefer to load the items as JSON and then iterate them and use google functions, eg:
var data = [<%="{x:50.44444,y:30.44444,speed:50},..." %>] // generate you JSON Here as array
for(var i = 0; i < data.length; i++){
map.addOverlay(new GMarker(new GLatLng(data[i].y,data[i].x),{ title: data[i].speed + 'Km/h'}));
}
so you will not repeat this part
map.addOverlay(new GMarker(new GLatLng(,),{ title: + 'Km/h'}));
which will increase the document size and page load
It's about as pretty as it gets.
Slightly better way IMO would be to do something like this:
var locations = <%= Html.ToJson(Model) %>
at the top, and then your JavaScript would be pure JavaScript without embedded C# stuff.
PS: You would need to extend HtmlHelper
with a ToJson
method in order to do this.
ended up mixing both answers of Kronass and mookid.
Here is the final code for reference:
public static class MvcViewExtensions
{
public static string ToJson(this System.Web.Mvc.HtmlHelper helper, object obj) {
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(obj);
}
}
And the javascript in the view:
<script type='text/javascript'>
google.load("maps", "2");
$(document).ready(initializeReportMap);
function initializeReportMap() {
if (GBrowserIsCompatible()) {
// Convert the reports to JSON
var reports = <%= Html.ToJson(Model) %>
var map = new GMap2(document.getElementById('report_map_canvas'));
map.setCenter(new GLatLng(51.5, -0.1167), 3);
for(var i = 0; i < reports.length; i++){
map.addOverlay(new GMarker(new GLatLng(reports[i].latitude,reports[i].longitude),{ title: reports[i].speed + 'Km/h'}));
}
map.setUIToDefault();
}
}
</script>
Theres nothing wrong with preloading your data with the rendering of your page (which is effectivly what you are doing with the loop, perhaps you could output json within your page and write some javascript to eval it (which would cut down on repedative charaters ie map.addOverlay ...) You just have to lookout for unconstrained output from your model, you wouldnt want 1 000 000 records being rendered this way
Take a look at this project (Google map control for aspnet mvc). Maybe it can help you to create some helper that wrap the functionality you want.
精彩评论