-1

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

Igor
  • 1,384
  • 3
  • 17
  • 34

1 Answers1

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

iH8
  • 27,722
  • 4
  • 67
  • 76
  • I tried it before it works for me too, but i try to pass scope.geojson from FilteredGeojson function which after filtering has data and then i get infinitive digest loop and map is empty? – Igor Feb 10 '15 at 23:37
  • Could you try running the final filtered object through: http://geojsonlint.com/ (and don't forget to set it on FeatureCollection in the top navbar) Maybe your filters are corrupting your data. Or do you have a testcase we can look at somewhere? – iH8 Feb 11 '15 at 00:29
  • actually i think filters are not the issue here, i used FilteredGeojson() in view with ng-repeat and everything works fine, ufortunatelly i dont have any testcase. Or mayby there is other way how can i add geojson from rest into leaflet.js ? Before everything worked fine with angular-leaflet-directive, but its performance is very bad with many markers. – Igor Feb 11 '15 at 00:45
  • I've added another entirely different approach to a leaflet directive. Maybe that will work for you, i'm guessing it doesn't but i just thought i'de throw it in there, maybe it's a handier way of working for you and will allow you to debug you problem more easily. Oh and that you can loop over your features using ng-repeat doesn't mean your geojson is valid. You should really validate your dataset, to be sure. – iH8 Feb 11 '15 at 01:22
  • If your dataset is too big, you could always validate it yourself. Save and include this JS file: https://raw.githubusercontent.com/mapbox/geojsonhint/master/geojsonhint.js then use it like this `var errors = geojsonhint.hint($scope.geojson);` then check if there's something in the returned array – iH8 Feb 11 '15 at 01:34
  • I made new question with fiddler http://stackoverflow.com/questions/28464558/ng-repeat-causing-infinitive-digest-loop-when-passing-scope-to-leaflet-directive – Igor Feb 11 '15 at 21:38