Skip to content

Instantly share code, notes, and snippets.

@patrickarlt
Last active August 29, 2015 14:07
Show Gist options
  • Save patrickarlt/76f387d5f0b31a958dfb to your computer and use it in GitHub Desktop.
Save patrickarlt/76f387d5f0b31a958dfb to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="http://js.arcgis.com/3.11/esri/css/esri.css">
<script src="http://js.arcgis.com/3.11amd/"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<style>
html, body, #map {
margin: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body ng-app="demo">
<esri-map id="map" lat="45.523452" lng="-122.676207" zoom="12" basemap="topo">
<esri-feature-layer url="http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/Heritage_Trees_Portland/FeatureServer/0"></esri-feature-layer>
<esri-feature-layer url="http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/Portland_Parks/FeatureServer/0"></esri-feature-layer>
</esri-map>
<script>
var app = angular.module('demo', []);
app.directive('esriMap', function ($q) {
return {
restrict: 'E',
scope: false,
compile: function($element, $attrs){
// remove the id attribute from the main element
$element.removeAttr("id");
// append a new div inside this element, this is where we will create our map
$element.append("<div id=" + $attrs.id + "></div>");
// since we are using compile we need to return our linker function
// the 'link' function handles how our directive responds to changes in $scope
return function (scope, element, attrs, controller){
// link function
};
},
controller: function($scope, $element, $attrs){
// only do this once per directive this deferred will be resolved with the map and we can reuse the same deferred every time
var mapDeferred = $q.defer();
// start requiring components from the JS API
require([
'esri/map'
], function(Map){
// create the map object
var map = new Map($attrs.id, {
center: [$attrs.lng, $attrs.lat],
zoom: $attrs.zoom,
basemap: $attrs.basemap
});
// resolve out deferred with the map object now this will always return the same map object.
mapDeferred.resolve(map);
});
// this method returns the promise that will be resolved with the map so we can use it in other methods
this.getMap = function(){
return mapDeferred.promise;
};
// adds the layer, returns the promise that will be resolved with the result of map.addLayer. Uses getMap internally to get the map instance once it is ready
this.addLayer = function(layer){
return this.getMap().then(function(map){
return map.addLayer(layer)
});
};
}
}
});
app.directive('esriFeatureLayer', function($q){
// this object will tell angular how our directive behaves
return {
// only allow esriFeatureLayer to be used as an element (<esri-feature-layer>)
restrict: 'E',
// require the esriFeatureLayer to have its own controller as well an esriMap controller
// you can access these controllers in the link function
require: ["esriFeatureLayer", "^esriMap"],
// replace this element with our template.
// since we aren't declaring a template this essentially destroys the element
replace: true,
// define an interface for working with this directive
controller: function($scope, $element, $attrs){
// create a deferred to represent our layer
var layerDeferred = $q.defer();
// load JS API components
require([
'esri/layers/FeatureLayer'
], function(FeatureLayer){
// create layer
var layer = new FeatureLayer($attrs.url);
// resolve deferred with layer
layerDeferred.resolve(layer);
});
// return the defered that will be resolved with the feature layer
this.getLayer = function(){
return layerDeferred.promise;
};
},
// now we can link our directive to the scope, but we can also add it to the map..
link: function(scope, element, attrs, controllers){
// controllers is now an array of the controllers from the 'require' option
var layerController = controllers[0];
var mapController = controllers[1];
// get our layer instance and pass it to the map controller (which will load the map and then add the layer returning a promise)
layerController.getLayer().then(function(layer){
return mapController.addLayer(layer);
});
}
};
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment