2012-10-19 7 views
7

Folgende Directie-Code ist von http://jsfiddle.net/M6RPn/26/ Ich möchte einen JSON-Feed, der viele Lat und lange hat .. Ich kann ein Json mit $ Ressource oder $ http in Angular leicht aber wie kann ich es zu füttern Anweisung, um etwas auf der Karte zu kartieren?angularjs mit Leafletjs

module.directive('sap', function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     template: '<div></div>', 
     link: function(scope, element, attrs) { 
      var map = L.map(attrs.id, { 
       center: [40, -86], 
       zoom: 10 
      }); 
      //create a CloudMade tile layer and add it to the map 
      L.tileLayer('http://{s}.tile.cloudmade.com/57cbb6ca8cac418dbb1a402586df4528/997/256/{z}/{x}/{y}.png', { 
       maxZoom: 18 
      }).addTo(map); 

      //add markers dynamically 
      var points = [{lat: 40, lng: -86},{lat: 40.1, lng: -86.2}]; 
      for (var p in points) { 
       L.marker([points[p].lat, points[p].lng]).addTo(map); 
      } 
     } 
    }; 
}); 

Antwort

11

Ich weiß nicht viel über Leaflet oder was Sie zu tun versuchen, aber ich würde annehmen, dass Sie wollen einige Koordinaten passieren in von dem Controller zu Ihrer Richtlinie?

Es gibt tatsächlich viele Möglichkeiten, dies zu tun ... die besten davon umfassen die Nutzung von Umfang.

Hier ist eine Möglichkeit, Daten aus dem Controller zu Ihrer Richtlinie weitergeben müssen:

module.directive('sap', function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     template: '<div></div>', 
     link: function(scope, element, attrs) { 
      var map = L.map(attrs.id, { 
       center: [40, -86], 
       zoom: 10 
      }); 
      //create a CloudMade tile layer and add it to the map 
      L.tileLayer('http://{s}.tile.cloudmade.com/57cbb6ca8cac418dbb1a402586df4528/997/256/{z}/{x}/{y}.png', { 
       maxZoom: 18 
      }).addTo(map); 

      //add markers dynamically 
      var points = [{lat: 40, lng: -86},{lat: 40.1, lng: -86.2}]; 
      updatePoints(points); 

      function updatePoints(pts) { 
       for (var p in pts) { 
        L.marker([pts[p].lat, pts[p].lng]).addTo(map); 
       } 
      } 

      //add a watch on the scope to update your points. 
      // whatever scope property that is passed into 
      // the poinsource="" attribute will now update the points 
      scope.$watch(attr.pointsource, function(value) { 
       updatePoints(value); 
      }); 
     } 
    }; 
}); 

Hier ist das Markup. Hier fügen Sie das Punktquellenattribut hinzu, nach dem die Linkfunktion sucht, um die $ watch einzurichten.

<div ng-app="leafletMap"> 
    <div ng-controller="MapCtrl"> 
     <sap id="map" pointsource="pointsFromController"></sap> 
    </div> 
</div> 

Dann in Ihrem Controller haben Sie eine Eigenschaft, die Sie nur aktualisieren können.

function MapCtrl($scope, $http) { 
    //here's the property you can just update. 
    $scope.pointsFromController = [{lat: 40, lng: -86},{lat: 40.1, lng: -86.2}]; 

    //here's some contrived controller method to demo updating the property. 
    $scope.getPointsFromSomewhere = function() { 
    $http.get('/Get/Points/From/Somewhere').success(function(somepoints) { 
     $scope.pointsFromController = somepoints; 
    }); 
    } 
} 
+0

Above Antwort war sehr hilfreich .. Nur eine Sache, die ich zu erreichen versuchen, alle Markierungen von der Funktion löschen .. Jede Idee? – MomentH

+0

eckig wird nicht immer ausgelöst, wenn Sie ein Array zurücksetzen, indem Sie es reinitialisieren, wie Sie sicher schon versucht haben. Also zuerst können Sie versuchen: '$ scope.pointsFromController = [];' was möglicherweise nicht funktioniert ... wenn das nicht funktioniert, dann können Sie es tun, indem Sie die Elemente manuell entfernen: '$ scope.pointsFromController.splice (0, $ scope.pointsFromController.length); ' –

5

Ich baute kürzlich eine App Angular JS und Leaflet verwenden. Sehr ähnlich zu dem, was Sie beschrieben haben, einschließlich Standortdaten aus einer JSON-Datei. Meine Lösung ist ähnlich wie blesh.

Hier ist der grundlegende Prozess.

Ich habe ein <map> Element auf einer meiner Seiten. Ich habe dann eine Richtlinie, die das <map> Element durch die Leaflet Map ersetzt. Mein Setup ist etwas anders, weil ich die JSON-Daten in einer Factory lade, aber ich habe es für Ihren Anwendungsfall angepasst (Entschuldigung, falls es Fehler gibt). Laden Sie Ihre JSON-Datei innerhalb der Richtlinie und durchlaufen Sie dann jeden Ihrer Standorte (Sie müssen Ihre JSON-Datei auf kompatible Weise einrichten). Zeigen Sie dann einen Marker an jedem Breitengrad an.

HTML

<map id="map" style="width:100%; height:100%; position:absolute;"></map> 

Richtlinie

app.directive('map', function() { 
return { 
    restrict: 'E', 
    replace: true, 
    template: '<div></div>', 
    link: function(scope, element, attrs) { 

     var popup = L.popup(); 
     var southWest = new L.LatLng(40.60092,-74.173508); 
     var northEast = new L.LatLng(40.874843,-73.825035);    
     var bounds = new L.LatLngBounds(southWest, northEast); 
     L.Icon.Default.imagePath = './img'; 

     var map = L.map('map', { 
      center: new L.LatLng(40.73547,-73.987856), 
      zoom: 12, 
      maxBounds: bounds, 
      maxZoom: 18, 
      minZoom: 12 
     }); 



     // create the tile layer with correct attribution 
     var tilesURL='http://tile.stamen.com/terrain/{z}/{x}/{y}.png'; 
     var tilesAttrib='Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://creativecommons.org/licenses/by-sa/3.0">CC BY SA</a>.'; 
     var tiles = new L.TileLayer(tilesURL, { 
      attribution: tilesAttrib, 
      opacity: 0.7, 
      detectRetina: true, 
      unloadInvisibleTiles: true, 
      updateWhenIdle: true, 
      reuseTiles: true 
     }); 
     tiles.addTo(map); 

     // Read in the Location/Events file 
     $http.get('locations.json').success(function(data) { 
      // Loop through the 'locations' and place markers on the map 
      angular.forEach(data.locations, function(location, key){ 

       var marker = L.marker([location.latitude, location.longitude]).addTo(map); 

      }); 
     }); 
    } 
}; 

Beispiel JSON Datei

{"locations": [  
{ 
    "latitude":40.740234, 
    "longitude":-73.995715 
    }, 
{ 
    "latitude":40.74277, 
    "longitude":-73.986654 
    }, 
{ 
    "latitude":40.724592, 
    "longitude":-73.999679 
    } 
]} 
1

Richtlinien und mvc in AngularJS sind verschiedene Technologien. Anweisungen werden normalerweise beim Laden der Seite ausgeführt. Direktiven sind mehr für die Arbeit mit/mit HTML und XML. Sobald Sie JSON haben, ist es am besten, das mvc-Framework zu verwenden, um zu arbeiten.

Nachdem die Seite gerendert wurde, müssen Sie häufig $ scope ausführen, um die Änderung auf der Seite zu registrieren. $ Apply() oder $ compile.

Wie auch immer, der beste Weg, um einen Dienst in eine Direktive zu bekommen, ist die Verwendung des Dependency-Injection-Frameworks.

Ich bemerkte den Geltungsbereich: True oder Bereich: {} fehlte in Ihrer Anweisung. Dies hat großen Einfluss darauf, wie gut die Richtlinie mit übergeordneten Controllern funktioniert.

app.directive('mapThingy',['mapSvc',function(mapSvc){ 
    //directive code here. 

}]); 

app.service('mapSvc',['$http',function($http){ 
//svc work here. 
}]) 

Richtlinien werden durch camelCase-Abgleich angewendet. Ich würde vermeiden zu verwenden oder wegen eines Problems mit IE. Alternative wäre

<div map-thingy=""></div> 
1

sein, dass du in deinem Controller Unter der Annahme,

$scope.points = // here goes your retrieved data from json 

und Ihre Richtlinie Vorlage:

<sap id="nice-map" points="points"/> 

dann in Ihrer Richtlinie Definition Sie verwenden können, die "=" simbol Einrichten einer bidirektionalen Bindung zwischen dem Anweisungsbereich und dem übergeordneten Bereich

module.directive('sap', function() { 
return { 
    restrict: 'E', 
    replace: true, 
    scope:{ 
     points:"=points" 
    }, 
    link: function(scope, element, attrs) { 
     var map = L.map(attrs.id, { 
      center: [40, -86], 
      zoom: 10 
     }); 
     L.tileLayer('http://{s}.tile.cloudmade.com/57cbb6ca8cac418dbb1a402586df4528/997/256/{z}/{x}/{y}.png', { 
      maxZoom: 18 
     }).addTo(map); 

     for (var p in points) { 
      L.marker([p.lat, p.lng]).addTo(map); 
     } 
    } 
}; 
}); 

Anstatt die Markierungen direkt in die Karte einzufügen, wird empfohlen, zuerst die Marker zu einer L.featureGroup hinzuzufügen und diese L.featureGroup dann zur Map hinzuzufügen, da sie über das ClearLayers() -Methode verfügt, das gespeichert wird Sie Kopfschmerzen beim Aktualisieren Ihrer Marker.

grupo = L.featureGroup(); 
grupo.addTo(map); 

for (var p in points) { 
    L.marker([p.lat, p.lng]).addTo(grupo); 
} 


// remove all markers 
grupo.clearLayers(); 

Ich hoffe, das hilft, prost

Verwandte Themen