2012-10-04 9 views
7

Ich mache eine einzelne Seite App, wo in der zweiten Ansicht muss ich die Google-Karte anzeigen. Ich verwende die Google Maps-API, in der das Kartenobjekt erstellt werden soll.Google Maps und knockoutjs

var map = new google.maps.Map(mapId, { 
     zoom: 5, 
     center: new google.maps.LatLng(55, 11), 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
}); 

Der Parameter mapId ist mir ein Problem zu geben. Die Ansicht enthält ein Div mit ID say "mapId", aber ich bin nicht in der Lage, die ID zu bekommen und so kann die Karte nicht angezeigt werden. Ich habe versucht, HTML-Bindung, Attributbindung, aber es funktioniert nicht. Ich bin neu im KO-Modus. Bitte schlagen Sie eine Methode vor.

+1

Können Sie das konkretisieren in Bezug auf, warum Sie nicht die ID des Elements bekommen? Ist die zweite Ansicht ein Modal/Dialog? –

+0

Die zweite Ansicht ist ein Modal. und PS- Ich benutze knockout.js. Um auf die ID zuzugreifen, verwende ich die jquery-Syntax $ ('# mapId') [0] -Syntax, sie gibt null oder nicht definiert zurück. Wenn ich eine attribute Bindung für die ID verwende, wird der Wert der ID zugewiesen, aber es repräsentiert kein div-Element (das für das map-Objekt benötigt wird), sondern nur eine Zeichenkette, die gleich dem ID-Wert ist. – Empty

+0

Könnten Sie Code auf jsfiddle oder in Ihrer Frage posten? Ich denke, wenn Sie das Google Map-Objekt initialisieren * vor * Knockout hat eine Chance, die ID an Ihr Element zu binden. –

Antwort

0

Statt mapId Sie wollen document.getElementById('map') verwenden, wo 'map' ist die ID des div die Karte, die (<div id="map"></div>). This jsFiddle sollte helfen.

19

Sie sollten eine benutzerdefinierte Bindung wie verwenden so:

ko.bindingHandlers.map = { 

    init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     var mapObj = ko.utils.unwrapObservable(valueAccessor()); 
     var latLng = new google.maps.LatLng(
      ko.utils.unwrapObservable(mapObj.lat), 
      ko.utils.unwrapObservable(mapObj.lng)); 
     var mapOptions = { center: latLng, 
          zoom: 5, 
          mapTypeId: google.maps.MapTypeId.ROADMAP}; 

     mapObj.googleMap = new google.maps.Map(element, mapOptions); 
    } 
}; 

Ihre HTML würde wie folgt aussehen:

<div id="mapDiv" data-bind="style:{width:'300px',height:'300px'},map:myMap"></div> 

Schließlich Ihrer Ansicht Modell:

function MyViewModel() { 
    var self = this; 
    self.myMap = ko.observable({ 
     lat: ko.observable(55), 
     lng: ko.observable(11)}); 
} 

Hier ist ein fiddle das tut ein bisschen mehr als das, was Sie fragen, aber sollte auch für Ihren Fall gut funktionieren.

+1

Wie drücken Sie dann mehr Punkte in einer einzelnen Karte? Ich habe observableArray versucht, aber es funktioniert nicht, kann mir jemand dabei helfen? –

+0

@kougiland - In der Bindung habe ich einen Verweis auf das Google Map-Objekt in der googleMap-Eigenschaft des Ansichtsmodells (im Beispiel "myMap") gespeichert. Sie können wie self.myMap(). GoogleMap darauf zugreifen und Marker direkt hinzufügen. Wenn Sie eine Bindung wünschen, die die Kartenmarkierungen synchron mit einem beobachtbaren Array hält, sollten Sie eine andere Frage stellen. – schmidlop

3

Ich habe "schmidlop" Bindung geändert, um Marker bei Änderung der Eingänge (lat lange Eingänge) und Marker immer in der Mitte der Karte zu setzen.

Html

<input data-bind="value: mapOne().lat" /> 

<input data-bind="value: mapOne().lng" /> 

Bindung, Fügen Sie diese in irgendeiner js Datei und es in html.

ko.bindingHandlers.map = { 
     init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
      $("#" + element.getAttribute("id")).data("mapObj",""); 
      mapObj = ko.utils.unwrapObservable(valueAccessor()); 
      var latLng = new google.maps.LatLng(
       ko.utils.unwrapObservable(mapObj.lat), 
       ko.utils.unwrapObservable(mapObj.lng)); 
      var mapOptions = { center: latLng, 
           zoom: 12, 
           mapTypeId: google.maps.MapTypeId.ROADMAP}; 

      mapObj.googleMap = new google.maps.Map(element, mapOptions); 

      mapObj.marker = new google.maps.Marker({ 
       map: mapObj.googleMap, 
       position: latLng, 
       draggable: true 
      });  

      mapObj.onChangedCoord = function(newValue) { 
       var latLng = new google.maps.LatLng(
        ko.utils.unwrapObservable(mapObj.lat), 
        ko.utils.unwrapObservable(mapObj.lng)); 

       mapObj.googleMap.setCenter(latLng); 
       mapObj.marker.setPosition(latLng);     
      }; 

      mapObj.onMarkerMoved = function(dragEnd) { 
       var latLng = mapObj.marker.getPosition(); 
       mapObj.lat(latLng.lat()); 
       mapObj.lng(latLng.lng()); 
      }; 

      mapObj.lat.subscribe(mapObj.onChangedCoord); 
      mapObj.lng.subscribe(mapObj.onChangedCoord); 

      google.maps.event.addListener(mapObj.marker, 'dragend', mapObj.onMarkerMoved); 

      $("#" + element.getAttribute("id")).data("mapObj",mapObj); 
     } 
    }; 

Ansicht Modell

self.mapOne = ko.observable();  


self.mapOne({'lat':ko.observable(87.22),'lng':ko.observable(27.22)});