Angular code reuse - with Controller

by jec006

HTML

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.5.1/leaflet.css">
<script src="http://cdn.leafletjs.com/leaflet-0.5.1/leaflet.js"></script>
<div class="wrapper" ng-app="App">
    <map center="[40, 20]" zoom="3" no-zoom>
        <marker latlng="[40, 30]"></marker>
        <circle latlng="[35, -25]" radius="100" color="#d23c3c"></circle>
    </map>
    <div class="seperator"></div>
    <map center="[40, -90]" zoom="3">
        <circle latlng="[38, -78]" radius="20"></circle>
        <marker latlng="[40, -85]"></marker>
        <marker latlng="[22, -105]"></marker>
        <marker latlng="[35, -120]"></marker>
    </map>
</div>

CSS

.map-holder {
    display:block;
    height:300px;
}

.seperator {
    height:0px;
    border:1px solid #999;
    margin:15px 50px;
}

JavaScript

var app = angular.module('App', []);

/**
 * NOTE: Because I'm nesting directives and expecting the scopes to reflect the DOM,
 * the map component cannot have a template / you'll have to do the transclusion yourself.
 */

app.directive('map', function() {
    return {
        scope: {
            center: '@',
            zoom: '@'
        },
        restrict: 'EA',
        controller: function mapController ($scope) {
            $scope.queue = [];
            this.addToMap = function(shape) {
                if ($scope.map) {
                    shape.addTo($scope.map);
                } else {
                    $scope.queue.push(shape);    
                }
            };
        },
        link: function mapLink (scope, element, attrs) {
            element.addClass('map-holder');
            scope.map = new L.Map(element[0]);
            new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { 
                attribution: 'Map data © OpenStreetMap contributors'
            }).addTo(scope.map);
            
            scope.$watch('center + zoom', function() {
                scope.map.setView(getLatLng(scope.center), scope.zoom || 2);
            });

            attrs.$observe('noZoom', function(val) {
                var func = 'enable';
                if (val != undefined) {
                    func = 'disable';
                    scope.map.zoomControl.removeFrom(scope.map);
                } else if (!scope.map.zoomControl._map) {
                    scope.map.zoomControl.addTo(scope.map);
                }

                scope.map.doubleClickZoom[func]();
                scope.map.scrollWheelZoom[func]();
                scope.map.boxZoom[func]();
            });
            
            angular.forEach(scope.queue, function(shape) {
                shape.addTo(scope.map);
            });
        }
    };
}).directive('latlng', function() {
    return function latlngLink (scope, element, attr) {
        var cancel = angular.noop;
...