2013-07-13 52 views
6

我將Google地圖合併到我的MVC 4應用程序中。相當簡單。不過,我有一個關於動態添加多個標記的最佳方法的問題。我的用戶將通過調用控制器上的操作方法來搜索要銷售的物品列表,並且我希望能夠向他們展示物品以及地圖上每個物品的位置。我不確定的是如何或最好的方式,動態地添加標記到地圖上,這是客戶端中的所有JavaScript。基本上,我希望能夠將所有標記信息從MVC服務器代碼發送到客戶端,但不確定它可以或應該以這種方式完成。MVC 4和Google Maps API v3

+0

用戶後點擊搜索按鈕,是更新的地圖嘛?或者搜索結果也顯示爲文本,因此它們也會更新? – mostruash

+0

搜索結果也更新。 – Hosea146

+0

還有一個問題。通過動態的,你的意思是說,搜索結果是通過對你的行爲的AJAX請求異步更新的? – mostruash

回答

10

在(http://docs.angularjs.org/api/ng $ HTTP)。項目我現在正在處理,這是我們如何處理它:

讓主ViewModel被稱爲FooViewModel

的ViewModels:

public class FooViewModel 
{ 
    // Your search results: 
    public IEnumerable<FooWithLocationViewModel> Foos { get; set; } 

    // Properties for your search filter: 
    public decimal? MaxPrice { get; set; } 
    public CityEnum? City { get; set; } 
    ... 
} 

public class FooWithLocationViewModel 
{ 
    public string Name { get; set; } 
    public decimal Price { get; set; } 
    ... 
    public double Latidude { get; set; } 
    public double Longitude { get; set; } 
    ... 
} 

在視圖中,存在用於每個FooWithLocationViewModel一個<div>。我們將利用data-*屬性,其在HTML5中是有效的:

查看:

@model FooViewModel 

... 

@foreach(FooWithLocationViewModel foo in Model.Foos) 
{ 
    <div class="foo" data-latitude="@(foo.Latitude)" 
     data-longitude="@(foo.Longitude)"> 
     <span>@foo.Name</span> 
     <span>@foo.Price</span> 
     ... 
    </div> 
} 

<div id="map-canvas"></div> 

現在,是時候爲JavaScript,我假設你正在使用JQuery:

初始化地圖,添加標記,並將它們存儲在markers陣列:

function initialize() { 
    var foos = $(".foo"); 
    var markers = new Array(); 
    var mapOptions = { 
     ... 
    }}; 
    var mapCanvas = document.getElementById('map-canvas'); 
    if (mapCanvas != null) { 
     map = new google.maps.Map(mapCanvas, mapOptions); 

     $.each(foos, function (key, value) { 
      markers[key] = new google.maps.Marker({ 
       map: map, 
       draggable: false, 
       animation: google.maps.Animation.DROP, 
       position: new google.maps.LatLng(
        Number($(value).attr("data-latitude")), 
        Number($(value).attr("data-longitude") 
       )); 
      }); 

      google.maps.event.addListener(markers[key], 'click', function() { 
       // If you need this... 
      }); 
     }); 
    } 
} 

什麼好的這種做法,一切都在做福初始化您的Google地圖。因此,您的腳本不必嵌入您的視圖中。我們正在使用HTML5友好的方法。這很簡單。

+1

這是一個很好的答案!它大致上是我在想的想法,但是通過使用數據作爲傳遞機制,我改進了我的想法,但我只是傾倒出一大塊JavaScript,但是這樣更加精美。 – rtpHarry

+0

@rtp哈利,謝謝。希望它能幫助別人。 – mostruash

+0

作爲一個溫和的擴展,如果你想給SPANS一個類或者一些描述的標識符,你可以重新使用這些信息來生成標記內容。比嵌入JS或數組更好。 – stefancarlton

2

使用Web API並將其全部異步處理。將JSON對象傳遞迴客戶端,解析出您的信息,刪除舊標記並添加新標記。您的評論後

編輯:

如果您發佈一些什麼你試過,不能夠得到再到工作,我們可以幫助你和你正在運行到的問題。如果你是剛剛開始:

http://www.asp.net/web-api - 偉大的教程使用Web API http://angularjs.org/ - 退房角的GET請求和你的結果綁定到UI

+0

謝謝。但是,對於150個重要點,我正在尋找更多的東西。 – Hosea146

0

想建議的方法對這一要求:

  1. 搜索按鈕點擊 - 無論是(POST請求或AJAX POST),將請求發送到服務器。

  2. 在服務器'search()'動作上執行搜索。

  3. search()操作有兩個責任 - 1.顯示搜索結果。 2.在地圖上顯示相應的標記

  4. 搜索結果將是數據和表示,是'div'/'table/tr/td'。這種表示 在服務器上生成,而不使用任何客戶端資源和客戶端處理時間。所以'SearchView'可以返回數據和表示。

  5. 另一個責任是顯示與每個搜索結果對應的標記。這完全是客戶的責任。因此,讓我們與第一責任分開。使用JSON序列化庫在'SearchView'中注入序列化的'markers'json數組,而不是將其與搜索結果混合。唯一一次您可能希望將標記詳細信息與每個搜索結果緊密綁定的情況是,您希望單擊單個搜索結果時突出顯示標記。用例最初可以顯示所有搜索結果並顯示所有標記。然後當用戶點擊/懸停時(考慮到這不是針對移動設備的,因爲懸停無法在那裏工作)單個搜索結果,您可以重新定位標記或爲選定的搜索結果添加標籤或更多信息。

  6. 此外,您可能希望將腳本放在單獨的文件中,以避免在每個搜索操作中加載該腳本。從SearchView中,您可以調用'InitializeMap()'JS函數,將JSON序列化標記和初始地圖位置傳遞給它。

  7. 使用JSON會是更好的方法,它提供了將應用程序輕鬆轉換爲AJAX的未來靈活性。而且它比使用Jquery解析HTML獲取標記細節更快。

    function InitializeMap(initialMapPosition,markers){ 
    var latlng = new google.maps.LatLng(initialMapPosition.latitude,initialMapPosition.longitude); 
    var options = { 
        zoom: 15, 
        center: latlng, 
        mapTypeId: google.maps.MapTypeId.ROADMAP // this could be as per your requirement. 
        }; 
    
    var map = new google.maps.Map($('#map-canvas')[0], options); 
    // Place markers on map 
    for(i = 0; i < markers.length; i++) { 
        var latLng = new google.maps.LatLng(markers[i].lat, markers[i].lng); 
        var marker = new google.maps.Marker({ 
         position: latLng, 
         map: map 
        }); 
    } 
    

    }

+0

關於第7點的解釋:解析HTML(在客戶端完成)與以計算方式顯示Google Map控件相比沒有任何意義。所以它絕對不是一個負擔。 – mostruash

+0

同意速度(儘管它取決於搜索結果的數量)。但對於未來的變化,擁有JSON對象肯定是一個不錯的選擇。 –

0

這裏是我關於這個問題的看法。

最近,我做了一個項目,這是一個單獨的頁面,AJAX驅動的Web應用程序(我知道你不是在尋找一個基於AJAX的解決方案,但留在我身邊)。

我在該應用程序中集成了Google地圖,該地圖用於顯示不同實體的位置。

當用戶搜索某些東西時,而不是在瀏覽器中進行地理編碼(有時非常慢),我將請求發送到服務器。在服務器上,傳入的文本採用地理編碼(使用Google API),並將結果緩存在本地數據庫中供以後使用。如果再次發出同樣的請求,我會從數據庫中獲取地理座標並將其發送回客戶端。

返回類型非常簡單。即

public class Marker 
{ 
    public double Lat{set;get;} 
    public double Lon{set;get;} 
    public string Title{set;get;} 
} 

在客戶端,我想簡單地遍歷目錄,並繪製地圖上的標記(標記繪圖比請求地理編碼更快)。

現在,同樣可以在回發。所有你需要做的就是,在你的初始化函數調用

var markers = @Html.Action("GetMarkers") 

這將填補VAR標記與所有的標記,然後你可以遍歷列表。

記住的GetMarkers返回類型是

public JsonResult GetMarkers() 
{ 
    ... 
    // returns List<Markers> 
}