2013-07-13 19 views
6

Włączam Mapy Google do mojej aplikacji MVC 4. Dość proste do zrobienia. Mam jednak pytanie dotyczące najlepszego sposobu dynamicznego dodawania wielu markerów. Moi użytkownicy będą szukać listy przedmiotów na sprzedaż, poprzez wywołanie metody działania na kontrolerze i chcę móc pokazać im elementy i lokalizację każdego z nich na mapie. Nie jestem pewien, jak lub najlepiej, aby dynamicznie dodawać znaczniki do mapy, która jest wszystkim JavaScriptem w kliencie. Zasadniczo chciałbym móc przesłać klientowi wszystkie informacje o znacznikach z kodu serwera MVC, ale nie jestem pewien, czy można to zrobić, czy nie.MVC 4 i Google Maps API v3

+0

gdy użytkownik kliknie przycisk wyszukiwania, jest mapa Jedyną rzeczą, która jest aktualizowana? Czy wyniki wyszukiwania są również wyświetlane jako tekst, a zatem są również aktualizowane? – mostruash

+0

Wyniki wyszukiwania również zostały zaktualizowane. – Hosea146

+0

Jeszcze jedno pytanie.Czy oznacza to, że wyniki dynamiczne są aktualizowane asynchronicznie z żądaniami AJAX do Twoich działań? – mostruash

Odpowiedz

10

w (http://docs.angularjs.org/api/ng $ http). projekt, nad którym teraz pracuję, tak to sobie radzimy:

Niech główny ViewModel będzie nazywać się 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; } 
    ... 
} 

W widoku, jest <div> dla każdego FooWithLocationViewModel. Będziemy wykorzystywać data-* cechy, które są ważne w HTML5:

Widok:

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

Teraz nadszedł czas na JavaScripcie, jestem przy założeniu, że używasz JQuery:

Inicjowanie mapę , dodając znaczniki i przechowywanie ich w markers tablicy:

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

Co jest dobre na temat tego podejścia jest, wszystko odbywa się w fu nunch, który inicjuje twoją Mapę Google. Zatem twój skrypt nie musi być osadzony w twoim Widoku. Używamy podejścia przyjaznego HTML5. I to jest proste.

+1

To jest dobra odpowiedź! Chodziło mi o pomysł, ale my ulepszyliśmy moje pomysły, używając danych - jako mechanizmu dostarczania, po prostu zrzuciłem fragment kodu JavaScript, ale jest to o wiele bardziej dopracowane. – rtpHarry

+0

@rtpHarry, dziękuję. Mam nadzieję, że pomaga innym. – mostruash

+0

jako łagodne rozszerzenie, jeśli chcesz podać klasę lub identyfikator jakiegoś opisu, do SPANÓW możesz ponownie użyć tych informacji, jeśli chcesz wygenerować zawartość znacznika. Neater niż osadzanie JS lub tablic. – stefancarlton

2

Skorzystaj z internetowego interfejsu API i obsłużyj je wszystkie asynchronicznie. Przekaż obiekt JSON z powrotem do klienta, przeanalizuj informacje, usuń stare znaczniki i dodaj nowe.

EDIT po swoim komentarzu:

Jeśli po niektóre z czego próbowałem i nie udało się dostać do pracy to możemy pomóc w problemach używasz do. Jeśli dopiero zaczynasz:

http://www.asp.net/web-api - Wielka tutoriale na temat korzystania z API Web http://angularjs.org/ - Sprawdź kątowa dla żądania GET i wiążący wyniki z UI

+0

Dziękuję. Ale za 150 punktów rep, szukam trochę więcej niż to. – Hosea146

0

Chciałbym zaproponować podejście do tego wymogu:

  1. w wyszukiwarce kliknięcia przycisku - czy to żądanie POST (lub AJAX POST), wysłać żądanie do serwera.

  2. Wykonaj wyszukiwanie na serwerze "akcja wyszukiwania()".

  3. Istnieją dwie obowiązki działania search() - 1. Pokaż wynik wyszukiwania. 2. Pokaż odpowiednie znaczniki na mapie

  4. Wyniki wyszukiwania będą danymi i reprezentacją, czy to "div"/"table/tr/td".Ta reprezentacja jest generowana na serwerze bez użycia zasobów klienta i czasu przetwarzania po stronie klienta. Tak więc "SearchView" może zwrócić zarówno dane, jak i reprezentację.

  5. Kolejna odpowiedzialność polega na wyświetlaniu znaczników odpowiadających każdemu wynikowi wyszukiwania. Jest to całkowicie odpowiedzialność klienta. Więc trzymajmy to oddzielnie od pierwszej odpowiedzialności. Korzystając z biblioteki serializacji JSON wstrzyknij zserializowaną tablicę jsonów 'markers' w 'SearchView' zamiast mieszania jej z wynikiem wyszukiwania. Jedynym czasem, w którym możesz chcieć, aby szczegóły znaczników ściśle powiązać z każdym wynikiem wyszukiwania, jest podkreślenie znaczników po kliknięciu poszczególnych wyników wyszukiwania. Przykład użycia może początkowo przedstawiać wszystkie wyniki wyszukiwania i pokazywać wszystkie znaczniki. Następnie, gdy użytkownik klika/zatrzymuje się (biorąc pod uwagę, że nie jest on przeznaczony dla urządzeń przenośnych, ponieważ nie może tam pracować zawijanie), indywidualny wynik wyszukiwania można zmienić położenie znacznika lub dodać etykietę lub więcej informacji do wybranego wyniku wyszukiwania.

  6. Możesz również chcieć mieć skrypt w osobnym pliku, aby uniknąć ładowania go przy każdej akcji wyszukiwania. A z SearchView możesz po prostu wywołać funkcję "InitializeMap()" JS, przekazując ją znacznikom serializowanym JSON i początkowej pozycji mapy.

  7. Korzystanie z JSON byłoby lepszym podejściem i zapewnia przyszłą elastyczność w celu łatwej konwersji aplikacji na AJAX. Ponadto jest szybszy niż analizowanie kodu HTML za pomocą Jquery w celu uzyskania szczegółów znacznika.

    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

Wyjaśnienie dotyczące punktu 7: Analizowanie HTML (wykonywane po stronie klienta) jest niczym w porównaniu do wyświetlania kontrolki Google Map, w sensie obliczeniowym. Więc to absolutnie nie jest ciężarem. – mostruash

+0

Uzgodniono szybkość (zależy to jednak od liczby wyników wyszukiwania). Ale dla przyszłych zmian byłoby zdecydowanie dobrą opcją posiadania obiektu JSON. –

0

Oto moje myśli na ten temat.

Niedawno zrobiłem projekt, który był pojedynczą stroną, opartą na AJAX aplikacją sieciową (wiem, że nie szukasz rozwiązania opartego na AJAX, ale zostań ze mną).

Zintegrowałem mapy Google w tej aplikacji, które służyły do ​​pokazania lokalizacji różnych podmiotów.

Gdy użytkownik czegoś szukał, zamiast wykonywać Geo-Coding w przeglądarce (co było bardzo powolne), wysłałem żądanie do serwera. Na serwerze tekst przychodzący był kodowany geo (za pomocą Google API), a wynik był buforowany w lokalnej bazie danych do późniejszego wykorzystania. Jeśli ta sama prośba pojawiła się ponownie, pobieram Geo-kordinaty z DB i odsyłaję je do klienta.

Typ zwrotu był całkiem prosty. tj

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

Na kliencie, chciałbym po prostu iteracyjne nad listą i wykreślić znaczniki na mapie (kreślenia znaczników jest szybszy niż zainteresowanie Geo-kodowanie).

Teraz to samo można zrobić w poście. Wszystko co musisz zrobić, to w initialize wywołania funkcji

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

ten wypełni markery var z listą wszystkich znaczników, które można następnie iteracyjne.

Pamiętaj, rodzaj powrotu GetMarkers jest

public JsonResult GetMarkers() 
{ 
    ... 
    // returns List<Markers> 
} 
Powiązane problemy