2012-10-19 9 views
7

Następujący kod jest z http://jsfiddle.net/M6RPn/26/ Chcę uzyskać plik json, który ma wiele lat i długo .. Mogę uzyskać json z $ resource lub $ http w Angular łatwo, ale jak mogę go karmić do tego dyrektywę do mapowania rzeczy na mapie?angularjs z 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); 
      } 
     } 
    }; 
}); 

Odpowiedz

11

Nie wiem wiele o ulotki lub co próbujesz robić, ale ja zakładam, że chce przekazać jakieś współrzędne z kontrolera do dyrektywy?

Istnieje wiele sposobów na zrobienie tego ... najlepsze z nich obejmują zakres dźwigni.

Oto jeden sposób, aby przekazać dane z kontrolera do dyrektywy:

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

Oto znaczników. Tutaj dodajesz atrybut pointsource, którego funkcja link szuka, aby skonfigurować $ watch.

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

Następnie w kontrolerze masz właściwość, którą możesz po prostu zaktualizować.

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

Przede odpowiedź była bardzo pomocny .. Tylko jedna rzecz staram się osiągnąć to, aby usunąć wszystkie znaczniki z funkcji .. jakiś pomysł? – MomentH

+0

kątowe nie zawsze wyzwalane, jeśli po prostu zresetowałeś tablicę przez ponowne zainicjowanie, tak jak na pewno próbowałem. Najpierw wypróbuj to: '$ scope.pointsFromController = [];' co może nie działać ... jeśli to nie działa, możesz to zrobić, ręcznie usuwając elementy: '$ scope.pointsFromController.splice (0, $ scope.pointsFromController.length); ' –

5

Niedawno zbudowany aplikację używając Angular JS i Leaflet. Bardzo podobne do tego, co opisałeś, w tym dane o lokalizacji z pliku JSON. Moje rozwiązanie jest podobne do blesh.

Oto podstawowy proces.

Mam element <map> na jednej z moich stron. Następnie mam dyrektywę zastępującą element <map> mapą ulotek. Moja konfiguracja jest nieco inna, ponieważ ładuję dane JSON w fabryce, ale dostosowałem ją do twojego przypadku użycia (przepraszam, jeśli są błędy). W ramach dyrektywy załaduj plik JSON, a następnie przeprowadź pętlę przez każdą z Twoich lokalizacji (musisz skonfigurować plik JSON w kompatybilny sposób). Następnie wyświetlaj znacznik przy każdym lng/lng.

HTML

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

dyrektywa

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

      }); 
     }); 
    } 
}; 

JSON Przykładowy plik

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

dyrektyw i MVC w angularjs są różne technologie. Dyrektywy są zwykle wykonywane po załadowaniu strony. Dyrektywy są bardziej do pracy nad/z html i xml. Kiedy już masz JSON-a, najlepiej jak najlepiej wykorzystać framework mvc do pracy.

Po wyrenderowaniu strony, aby zastosować dyrektywy, często trzeba wykonać $ scope. $ Apply() lub $ compile, aby zarejestrować zmianę na stronie.

Tak czy inaczej, najlepszym sposobem na uzyskanie usługi w dyrektywie jest użycie schematu wtrysku zależności.

Zauważyłem zasięg: true lub scope: {} brakowało Twojej dyrektywy. Ma to duży wpływ na to, jak dobrze dyrektywa radzi sobie z kontrolerami nadrzędnymi.

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

}]); 

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

Dyrektywy są stosowane poprzez dopasowanie camelCase. Unikałbym używania lub z powodu problemu z IE. Alternatywą byłoby

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

Zakładając, że w kontrolerze masz

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

a dyrektywa szablon jest:

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

następnie wewnątrz definicji dyrektywy można użyć „=” simbol Aby ustawić dwukierunkowe powiązanie między zakresem dyrektywy a obszarem nadrzędnym:

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

Zamiast dodawać znaczniki bezpośrednio do mapy, zaleca się najpierw dodanie swoich znaczników do grupy L.featureGroup, a następnie dodanie do mapy L.featureGroup, ponieważ zawiera ona metodę clearLayers(), która pozwoli zaoszczędzić masz pewne bóle głowy przy aktualizacji znaczników.

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

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


// remove all markers 
grupo.clearLayers(); 

Mam nadzieję, że to pomaga, okrzyki