Angularjs, cannot pass data to geojsonLayer Leaflet

北城以北 提交于 2019-12-13 22:11:58

问题


So i try to create directive for leaflet.js, when i use factory inside directive, everything works just fine

(function() {
'use strict';
 angular
    .module('directoryAppMap')
    .directive('leafletDirective', function (Directory) {
        return {
            restrict: 'EA',
            template:'<div></div>',
            link: function (scope,element, attrs) {
                var map = L.map(attrs.id, {
                    center: [40, -86],
                    zoom: 2
                });
                //create a CloudMade tile layer and add it to the map
                L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
                    maxZoom: 18
                }).addTo(map);
                Directory.get(function (data) {
                  L.geoJson(data).addTo(map);
                });
            }
        };
    });
})();

In my controller i do some stuff and pass it to view

    $scope.geojson = {};
    $scope.FilteredGeojson = function () {
        var result;

        result = $filter('filter')($scope.data, $scope.search);
        result = $filter('offset')(result, $scope.currentPage *            $scope.pageSize);
        result = $filter('limitTo')(result, $scope.pageSize);
        $scope.geojson = result;
        return result;
    };

Everything works fine in table i use ng-repeat with FilteredGeojson() but when i try to pass $scope.geojson to directive, angular start infinite digest loop and map is without any geojson

to previous directive i use add

 scope: { 
 data: '='
 }

in view i pass

 data="geojson"

unfortunatelly i cannot use leaflet directive for angular, because with to many markers is very slow


回答1:


Did you remove the factory when trying that? This works for me:

Directive:

angular.module('app').directive('leaflet', [
  function () {
    return {
      restrict: 'EA',
      replace: true,
      scope: {
        data: "="
      },
      template: '<div></div>',
      link: function (scope, element, attributes) {
        var map = L.map(element[0], {
            center: [0, 0],
            zoom: 0
        });
        var tileLayer = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
            maxZoom: 18
        }).addTo(map);
        var geojsonLayer = L.geoJson(scope.data).addTo(map);
        map.fitBounds(geojsonLayer.getBounds());
      }
    };
  }
]);

Controller:

angular.module('app').controller('rootController', [
  '$scope',
  function ($scope) {
    $scope.geojson = {
      "type": "FeatureCollection",
      "features": [{
        "type": "Feature",
        "properties": {},
        "geometry": {
          "type": "Point",
          "coordinates": [45, 45]
        }
      },{
        "type": "Feature",
        "properties": {},
        "geometry": {
          "type": "Point",
          "coordinates": [-45, -45]
        }
      }]
    };
  }
]);

Template:

<leaflet data="geojson"></leaflet>

Here's the working example on Plunker: http://plnkr.co/edit/0cUudGJp2VwRtxFBMRqc?p=preview

As per request in the comments below another way to implement this, infact it's a completely different approach to a leaflet directive. Keeping all the logic in your controller. The callback method:

Directive:

angular.module('app').directive('leaflet', [
  function () {
    return {
      restrict: 'EA',
      replace: true,
      scope: {
        callback: "="
      },
      template: '<div></div>',
      link: function (scope, element, attributes) {
        scope.callback(L.map(element[0]));
      }
    };
  }
]);

Template:

<leaflet callback="callback"></leaflet>

Controller:

angular.module('app').controller('rootController', [
  '$scope',
  function ($scope) {
    $scope.geojson = {
      // See controller above
    };
    $scope.callback = function (map) {
      var tileLayer = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
        maxZoom: 18
      }).addTo(map);
      var layer = L.geoJson($scope.geojson).addTo(map);
      map.fitBounds(layer.getBounds());
    };
  }
]);

Here's a working example of this approach: http://plnkr.co/edit/0cUudGJp2VwRtxFBMRqc?p=preview



来源:https://stackoverflow.com/questions/28441363/angularjs-cannot-pass-data-to-geojsonlayer-leaflet

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!