在Angular 1.5组件中使用Leaflet?

时间:2017-04-12 19:33:30

标签: javascript leaflet angularjs

我正在尝试构建一个包含Leaflet映射的简单Angular 1.5组件。

这是我的组件JS:

// Extend the leaflet js to support the topo module
L.TopoJSON = L.GeoJSON.extend({
  addData: function(jsonData) { 
    if (jsonData.type === "Topology") {
      for (var key in jsonData.objects) {
        geojson = topojson.feature(jsonData, jsonData.objects[key]);
        L.GeoJSON.prototype.addData.call(this, geojson);
      }
    } else {
      L.GeoJSON.prototype.addData.call(this, jsonData);
    }
  }
});

angular
  .module('synthApp')
  .component('map', {
    templateUrl: 'app/components/map.template.html',
    controller: MapController,
    bindings: {
      name: '@'
    }
  });

MapController.$inject = [
  '$window',
  '$rootScope'
];

function MapController(
    $window,
    $rootScope
  ) {

  var $ctrl = this;

  $ctrl.map = null;
  $ctrl.markers = [];

  // Set layer style
  $ctrl.handleLayer = function(layer) {
    layer.setStyle({
      fillColor: '#eee',
      weight: 1,
      opacity: 1,
      color: '#aaa',
      fillOpacity: 1,
      clickable: false
    });
  };

  $ctrl.$onInit = function() {
    $ctrl.map = $window.L.map($ctrl.name, {
      maxZoom: 10,
      minZoom: 1,
      scrollWheelZoom: false,
      attributionControl: false,
      tap: false,
      touchZoom: true,
      zoomControl: true,
      crs: $window.L.CRS.EPSG4326
    });

    var topoLayer = new $window.L.TopoJSON();
    var td;
    $.getJSON("../map.json", function(json) {
      td = json;
      console.log(td);
    });

    topoLayer.addData(td);
    topoLayer.addTo($ctrl.map);
    topoLayer.eachLayer($ctrl.handleLayer);

    $ctrl.map.setView([0,0], 2);
  };
}

以下是app/components/map.template.html的内容:

<div id="$ctrl.name" style="background:#c2dfff;height:500px;width:100%">

我正在尝试使用这样的组件:

<map name="rt-world-2"></map>

但是,我在地图组件Error: Map container not found.中调用$ctrl.map = $window.L.map($ctrl.name, {...})的行上发现错误init

将Angular与Leaflet结合使用是否存在某些限制?任何想法错误信息的含义是什么?

1 个答案:

答案 0 :(得分:1)

在模板中:

<div id="$ctrl.name" style="background:#c2dfff;height:500px;width:100%">

id

替换id="{{$ctrl.name}}"属性的绑定表达式

然后使用$timeout包装地图初始化以确保呈现模板:

$ctrl.$onInit = function () {
    $timeout(function () {
       //map initialization goes here..
    });
};

实施例

&#13;
&#13;
angular
    .module('synthApp', [])
    .component('map', {
        //templateUrl: 'map.template.html',
        template: '<div id="{{$ctrl.name}}" style="background:#c2dfff;height:500px;width:100%"/>',
        controller: MapController,
        bindings: {
            name: '@'
        }
    });

MapController.$inject = [
    '$window',
    '$rootScope',
    '$timeout'
];

function MapController(
    $window,
    $rootScope,
    $timeout
) {

    var $ctrl = this;
    

    $ctrl.map = null;
    $ctrl.markers = [];



    $ctrl.$onInit = function () {
        $timeout(function () {
          
            $ctrl.map = $window.L.map($ctrl.name, {
                maxZoom: 10,
                minZoom: 1,
                scrollWheelZoom: false,
                attributionControl: false,
                tap: false,
                touchZoom: true,
                zoomControl: true,
                crs: $window.L.CRS.EPSG4326
            });

            $ctrl.map.setView([0, 0], 2);

            $window.L.tileLayer(
                'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
                { maxZoom: 18 }).addTo($ctrl.map);
        });

    };
}
&#13;
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />
<script src="//cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>


<div ng-app="synthApp">
    <map name="rt-world-2"></map>
</div>    
&#13;
&#13;
&#13;