From 927853c267b0980685ee641780769a573e22b2c2 Mon Sep 17 00:00:00 2001 From: Tom Wayson Date: Wed, 28 Oct 2015 13:58:40 -0700 Subject: [PATCH] created esri.core module as dependency of esri.map new folder structure - core - layers - map core includes: - esriLoader - esriRegistry - esriMapUtils - esriLayerUtils moved instance-specific code from esriLayerUtils into a base controller other layer controllers extend this base controller for shared functions --- gulpfile.js | 27 +++--- src/core/esri.core.module.js | 6 ++ src/{services => core}/esriLayerUtils.js | 89 +---------------- src/{services => core}/esriLoader.js | 4 +- src/{services => core}/esriMapUtils.js | 2 +- src/{services => core}/esriRegistry.js | 2 +- src/esri.map.module.js | 6 ++ src/layers/EsriLayerControllerBase.js | 95 +++++++++++++++++++ .../esriDynamicMapServiceLayer.controller.js | 8 +- .../esriDynamicMapServiceLayer.js | 8 +- .../esriFeatureLayer.controller.js | 11 ++- .../esriFeatureLayer.js | 8 +- .../esriInfoTemplate.js | 0 src/{directives => map}/esriLegend.js | 0 src/{directives => map}/esriMap.controller.js | 2 +- src/{directives => map}/esriMap.js | 8 +- 16 files changed, 149 insertions(+), 127 deletions(-) create mode 100644 src/core/esri.core.module.js rename src/{services => core}/esriLayerUtils.js (62%) rename src/{services => core}/esriLoader.js (97%) rename src/{services => core}/esriMapUtils.js (97%) rename src/{services => core}/esriRegistry.js (95%) create mode 100644 src/esri.map.module.js create mode 100644 src/layers/EsriLayerControllerBase.js rename src/{directives => layers}/esriDynamicMapServiceLayer.controller.js (85%) rename src/{directives => layers}/esriDynamicMapServiceLayer.js (89%) rename src/{directives => layers}/esriFeatureLayer.controller.js (73%) rename src/{directives => layers}/esriFeatureLayer.js (92%) rename src/{directives => layers}/esriInfoTemplate.js (100%) rename src/{directives => map}/esriLegend.js (100%) rename src/{directives => map}/esriMap.controller.js (99%) rename src/{directives => map}/esriMap.js (96%) diff --git a/gulpfile.js b/gulpfile.js index 6d88f43..9ea8c6f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -34,18 +34,21 @@ gulp.task('clean', function() { // and copy into dist folder and docs gulp.task('build-js', function() { return gulp.src([ - 'src/services/esriLoader.js', - 'src/services/esriRegistry.js', - 'src/services/esriMapUtils.js', - 'src/services/esriLayerUtils.js', - 'src/directives/esriMap.controller.js', - 'src/directives/esriMap.js', - 'src/directives/esriFeatureLayer.controller.js', - 'src/directives/esriFeatureLayer.js', - 'src/directives/esriDynamicMapServiceLayer.controller.js', - 'src/directives/esriDynamicMapServiceLayer.js', - 'src/directives/esriInfoTemplate.js', - 'src/directives/esriLegend.js']) + 'src/core/esri.core.module.js', + 'src/core/esriLoader.js', + 'src/core/esriRegistry.js', + 'src/core/esriMapUtils.js', + 'src/core/esriLayerUtils.js', + 'src/esri.map.module.js', + 'src/map/esriMap.controller.js', + 'src/map/esriMap.js', + 'src/map/esriLegend.js', + 'src/layers/EsriLayerControllerBase.js', + 'src/layers/esriFeatureLayer.controller.js', + 'src/layers/esriFeatureLayer.js', + 'src/layers/esriDynamicMapServiceLayer.controller.js', + 'src/layers/esriDynamicMapServiceLayer.js', + 'src/layers/esriInfoTemplate.js']) .pipe(concat('angular-esri-map.js')) .pipe(gulp.dest('dist')) .pipe(gulp.dest('docs/lib')) diff --git a/src/core/esri.core.module.js b/src/core/esri.core.module.js new file mode 100644 index 0000000..7f282f7 --- /dev/null +++ b/src/core/esri.core.module.js @@ -0,0 +1,6 @@ +(function(angular) { + 'use strict'; + + angular.module('esri.core', []); + +})(angular); diff --git a/src/services/esriLayerUtils.js b/src/core/esriLayerUtils.js similarity index 62% rename from src/services/esriLayerUtils.js rename to src/core/esriLayerUtils.js index d4c0723..2743e40 100644 --- a/src/services/esriLayerUtils.js +++ b/src/core/esriLayerUtils.js @@ -1,12 +1,7 @@ (function (angular) { 'use strict'; - angular.module('esri.map').factory('esriLayerUtils', function (esriLoader) { - - // test if a string value (i.e. directive attribute value) is true - function isTrue(val) { - return val === true || val === 'true'; - } + angular.module('esri.core').factory('esriLayerUtils', function (esriLoader) { // parse array of visible layer ids from a string function parseVisibleLayers(val) { @@ -45,26 +40,6 @@ // stateless utility service var service = {}; - // get common layer options from layer controller properties - service.getLayerOptions = function (layerController) { - - // read options passed in as either a JSON string expression - // or as a function bound object - var layerOptions = layerController.layerOptions() || {}; - - // visible takes precedence over layerOptions.visible - if (angular.isDefined(layerController.visible)) { - layerOptions.visible = isTrue(layerController.visible); - } - - // opacity takes precedence over layerOptions.opacity - if (layerController.opacity) { - layerOptions.opacity = Number(layerController.opacity); - } - - return layerOptions; - }; - // create a feature layer service.createFeatureLayer = function(url, layerOptions) { return esriLoader.require(['esri/layers/FeatureLayer', 'esri/InfoTemplate']).then(function(esriModules) { @@ -143,68 +118,6 @@ }); }; - // get layer info from layer and directive attributes - service.getLayerInfo = function(layer, attrs) { - return { - title: attrs.title || layer.name, - layer: layer, - // TODO: are these the right params to send - hideLayers: (attrs.hideLayers) ? attrs.hideLayers.split(',') : undefined, - defaultSymbol: (attrs.defaultSymbol) ? JSON.parse(attrs.defaultSymbol) : true - }; - }; - - // bind directive attributes to layer properties and events - service.bindLayerEvents = function(scope, attrs, layer, mapController) { - - // call load handler (if any) - if (attrs.load) { - if (layer.loaded) { - // layer is already loaded - // make layer object available to caller immediately - scope.layerCtrl.load()(layer); - } else { - // layer is not yet loaded - // wait for load event, and then make layer object available - layer.on('load', function() { - scope.$apply(function() { - scope.layerCtrl.load()(layer); - }); - }); - } - } - - // call updateEnd handler (if any) - if (attrs.updateEnd) { - layer.on('update-end', function(e) { - scope.$apply(function() { - scope.layerCtrl.updateEnd()(e); - }); - }); - } - - // watch the scope's visible property for changes - // set the visibility of the feature layer - scope.$watch('layerCtrl.visible', function(newVal, oldVal) { - if (newVal !== oldVal) { - layer.setVisibility(isTrue(newVal)); - } - }); - - // watch the scope's opacity property for changes - // set the opacity of the feature layer - scope.$watch('layerCtrl.opacity', function(newVal, oldVal) { - if (newVal !== oldVal) { - layer.setOpacity(Number(newVal)); - } - }); - - // remove the layer from the map when the layer scope is destroyed - scope.$on('$destroy', function() { - mapController.removeLayer(layer); - }); - }; - return service; }); diff --git a/src/services/esriLoader.js b/src/core/esriLoader.js similarity index 97% rename from src/services/esriLoader.js rename to src/core/esriLoader.js index c8ac035..80d40d3 100644 --- a/src/services/esriLoader.js +++ b/src/core/esriLoader.js @@ -1,15 +1,13 @@ (function(angular) { 'use strict'; - angular.module('esri.map', []); - /** * @ngdoc provider * @name esriLoader * @description * Use `esriLoader` to lazyload the ESRI ArcGIS API or to require API modules. */ - angular.module('esri.map').factory('esriLoader', function ($q) { + angular.module('esri.core').factory('esriLoader', function ($q) { /** * Load the ESRI ArcGIS API diff --git a/src/services/esriMapUtils.js b/src/core/esriMapUtils.js similarity index 97% rename from src/services/esriMapUtils.js rename to src/core/esriMapUtils.js index 5acfa63..60cd870 100644 --- a/src/services/esriMapUtils.js +++ b/src/core/esriMapUtils.js @@ -1,7 +1,7 @@ (function (angular) { 'use strict'; - angular.module('esri.map').factory('esriMapUtils', function ($q, esriLoader) { + angular.module('esri.core').factory('esriMapUtils', function ($q, esriLoader) { // construct Extent if object is not already an instance // e.g. if the controller or HTML view are only providing JSON diff --git a/src/services/esriRegistry.js b/src/core/esriRegistry.js similarity index 95% rename from src/services/esriRegistry.js rename to src/core/esriRegistry.js index d56a812..7a90a3b 100644 --- a/src/services/esriRegistry.js +++ b/src/core/esriRegistry.js @@ -1,7 +1,7 @@ (function (angular) { 'use strict'; - angular.module('esri.map').service('esriRegistry', function ($q) { + angular.module('esri.core').service('esriRegistry', function ($q) { var registry = {}; return { diff --git a/src/esri.map.module.js b/src/esri.map.module.js new file mode 100644 index 0000000..dc6c90c --- /dev/null +++ b/src/esri.map.module.js @@ -0,0 +1,6 @@ +(function(angular) { + 'use strict'; + + angular.module('esri.map', ['esri.core']); + +})(angular); diff --git a/src/layers/EsriLayerControllerBase.js b/src/layers/EsriLayerControllerBase.js new file mode 100644 index 0000000..3cb80a9 --- /dev/null +++ b/src/layers/EsriLayerControllerBase.js @@ -0,0 +1,95 @@ +(function(angular) { + 'use strict'; + + angular.module('esri.map').controller('EsriLayerControllerBase', function EsriLayerControllerBase() { + + // test if a string value (i.e. directive attribute value) is true + function isTrue(val) { + return val === true || val === 'true'; + } + + // get common layer options from layer controller properties + this.getLayerOptions = function () { + + // read options passed in as either a JSON string expression + // or as a function bound object + var layerOptions = this.layerOptions() || {}; + + // visible takes precedence over layerOptions.visible + if (angular.isDefined(this.visible)) { + layerOptions.visible = isTrue(this.visible); + } + + // opacity takes precedence over layerOptions.opacity + if (this.opacity) { + layerOptions.opacity = Number(this.opacity); + } + + return layerOptions; + }; + + + // get layer info from layer and directive attributes + this.getLayerInfo = function(layer, attrs) { + return { + title: attrs.title || layer.name, + layer: layer, + // TODO: are these the right params to send + hideLayers: (attrs.hideLayers) ? attrs.hideLayers.split(',') : undefined, + defaultSymbol: (attrs.defaultSymbol) ? JSON.parse(attrs.defaultSymbol) : true + }; + }; + + // bind directive attributes to layer properties and events + this.bindLayerEvents = function(scope, attrs, layer, mapController) { + + // call load handler (if any) + if (attrs.load) { + if (layer.loaded) { + // layer is already loaded + // make layer object available to caller immediately + scope.layerCtrl.load()(layer); + } else { + // layer is not yet loaded + // wait for load event, and then make layer object available + layer.on('load', function() { + scope.$apply(function() { + scope.layerCtrl.load()(layer); + }); + }); + } + } + + // call updateEnd handler (if any) + if (attrs.updateEnd) { + layer.on('update-end', function(e) { + scope.$apply(function() { + scope.layerCtrl.updateEnd()(e); + }); + }); + } + + // watch the scope's visible property for changes + // set the visibility of the feature layer + scope.$watch('layerCtrl.visible', function(newVal, oldVal) { + if (newVal !== oldVal) { + layer.setVisibility(isTrue(newVal)); + } + }); + + // watch the scope's opacity property for changes + // set the opacity of the feature layer + scope.$watch('layerCtrl.opacity', function(newVal, oldVal) { + if (newVal !== oldVal) { + layer.setOpacity(Number(newVal)); + } + }); + + // remove the layer from the map when the layer scope is destroyed + scope.$on('$destroy', function() { + mapController.removeLayer(layer); + }); + }; + }); + +})(angular); diff --git a/src/directives/esriDynamicMapServiceLayer.controller.js b/src/layers/esriDynamicMapServiceLayer.controller.js similarity index 85% rename from src/directives/esriDynamicMapServiceLayer.controller.js rename to src/layers/esriDynamicMapServiceLayer.controller.js index 9abd5b4..de2dfdf 100644 --- a/src/directives/esriDynamicMapServiceLayer.controller.js +++ b/src/layers/esriDynamicMapServiceLayer.controller.js @@ -1,14 +1,12 @@ (function(angular) { 'use strict'; - angular.module('esri.map').controller('esriDynamicMapServiceLayerController', function EsriDynamicMapServiceLayerController(esriLayerUtils) { + angular.module('esri.map').controller('EsriDynamicMapServiceLayerController', function EsriDynamicMapServiceLayerController($controller, esriLayerUtils) { var layerPromise; - // get feature layer options from layer controller properties - this.getLayerOptions = function() { - return esriLayerUtils.getLayerOptions(this); - }; + // extends layer controller base class + angular.extend(this, $controller('EsriLayerControllerBase')); // return the defered that will be resolved with the dynamic layer this.getLayer = function () { diff --git a/src/directives/esriDynamicMapServiceLayer.js b/src/layers/esriDynamicMapServiceLayer.js similarity index 89% rename from src/directives/esriDynamicMapServiceLayer.js rename to src/layers/esriDynamicMapServiceLayer.js index 3dd69b8..8d2953a 100644 --- a/src/directives/esriDynamicMapServiceLayer.js +++ b/src/layers/esriDynamicMapServiceLayer.js @@ -1,7 +1,7 @@ (function (angular) { 'use strict'; - angular.module('esri.map').directive('esriDynamicMapServiceLayer', function (esriLayerUtils) { + angular.module('esri.map').directive('esriDynamicMapServiceLayer', function () { // this object will tell angular how our directive behaves return { // only allow esriDynamicMapServiceLayer to be used as an element () @@ -35,7 +35,7 @@ bindToController: true, // define an interface for working with this directive - controller: 'esriDynamicMapServiceLayerController', + controller: 'EsriDynamicMapServiceLayerController', // now we can link our directive to the scope, but we can also add it to the map.. link: function (scope, element, attrs, controllers) { @@ -47,14 +47,14 @@ layerController.getLayer().then(function(layer){ // get layer info from layer object and directive attributes - var layerInfo = esriLayerUtils.getLayerInfo(layer, attrs); + var layerInfo = layerController.getLayerInfo(layer, attrs); // add the layer to the map mapController.addLayer(layer); mapController.addLayerInfo(layerInfo); // bind directive attributes to layer properties and events - esriLayerUtils.bindLayerEvents(scope, attrs, layer, mapController); + layerController.bindLayerEvents(scope, attrs, layer, mapController); }); } }; diff --git a/src/directives/esriFeatureLayer.controller.js b/src/layers/esriFeatureLayer.controller.js similarity index 73% rename from src/directives/esriFeatureLayer.controller.js rename to src/layers/esriFeatureLayer.controller.js index 5eeb37e..e4a41f2 100644 --- a/src/directives/esriFeatureLayer.controller.js +++ b/src/layers/esriFeatureLayer.controller.js @@ -1,13 +1,16 @@ (function(angular) { 'use strict'; - angular.module('esri.map').controller('esriFeatureLayerController', function EsriFeatureLayerController(esriLayerUtils) { + angular.module('esri.map').controller('EsriFeatureLayerController', function EsriFeatureLayerController($controller, esriLayerUtils) { var layerPromise; + // extends layer controller base class + angular.extend(this, $controller('EsriLayerControllerBase')); + // get feature layer options from layer controller properties - this.getLayerOptions = function() { - var layerOptions = esriLayerUtils.getLayerOptions(this); + this.getFeatureLayerOptions = function() { + var layerOptions = this.getLayerOptions(); // definitionExpression takes precedence over layerOptions.definitionExpression if (this.definitionExpression) { layerOptions.definitionExpression = this.definitionExpression; @@ -32,7 +35,7 @@ }; // create the layer - layerPromise = esriLayerUtils.createFeatureLayer(this.url, this.getLayerOptions()); + layerPromise = esriLayerUtils.createFeatureLayer(this.url, this.getFeatureLayerOptions()); }); })(angular); diff --git a/src/directives/esriFeatureLayer.js b/src/layers/esriFeatureLayer.js similarity index 92% rename from src/directives/esriFeatureLayer.js rename to src/layers/esriFeatureLayer.js index 929eeec..d03e7c1 100644 --- a/src/directives/esriFeatureLayer.js +++ b/src/layers/esriFeatureLayer.js @@ -1,7 +1,7 @@ (function(angular) { 'use strict'; - angular.module('esri.map').directive('esriFeatureLayer', function(esriLayerUtils) { + angular.module('esri.map').directive('esriFeatureLayer', function() { // this object will tell angular how our directive behaves return { // only allow esriFeatureLayer to be used as an element () @@ -35,7 +35,7 @@ bindToController: true, // define an interface for working with this directive - controller: 'esriFeatureLayerController', + controller: 'EsriFeatureLayerController', // now we can link our directive to the scope, but we can also add it to the map link: function(scope, element, attrs, controllers) { @@ -46,14 +46,14 @@ // get the layer object layerController.getLayer().then(function(layer){ // get layer info from layer object and directive attributes - var layerInfo = esriLayerUtils.getLayerInfo(layer, attrs); + var layerInfo = layerController.getLayerInfo(layer, attrs); // add the layer to the map mapController.addLayer(layer, 0); mapController.addLayerInfo(layerInfo); // bind directive attributes to layer properties and events - esriLayerUtils.bindLayerEvents(scope, attrs, layer, mapController); + layerController.bindLayerEvents(scope, attrs, layer, mapController); // additional directive attribute binding specific to this type of layer diff --git a/src/directives/esriInfoTemplate.js b/src/layers/esriInfoTemplate.js similarity index 100% rename from src/directives/esriInfoTemplate.js rename to src/layers/esriInfoTemplate.js diff --git a/src/directives/esriLegend.js b/src/map/esriLegend.js similarity index 100% rename from src/directives/esriLegend.js rename to src/map/esriLegend.js diff --git a/src/directives/esriMap.controller.js b/src/map/esriMap.controller.js similarity index 99% rename from src/directives/esriMap.controller.js rename to src/map/esriMap.controller.js index 6b17cfa..6717047 100644 --- a/src/directives/esriMap.controller.js +++ b/src/map/esriMap.controller.js @@ -1,7 +1,7 @@ (function(angular) { 'use strict'; - angular.module('esri.map').controller('esriMapController', function EsriMapController($attrs, $timeout, esriMapUtils, esriRegistry) { + angular.module('esri.map').controller('EsriMapController', function EsriMapController($attrs, $timeout, esriMapUtils, esriRegistry) { // update two-way bound scope properties based on map state function updateCenterAndZoom(scope, map) { diff --git a/src/directives/esriMap.js b/src/map/esriMap.js similarity index 96% rename from src/directives/esriMap.js rename to src/map/esriMap.js index 938ca22..bfe116e 100644 --- a/src/directives/esriMap.js +++ b/src/map/esriMap.js @@ -29,6 +29,9 @@ bindToController: true, + // directive api + controller: 'EsriMapController', + // replace tag with div with same id compile: function($element, $attrs) { @@ -47,10 +50,7 @@ controller.bindMapEvents(scope, attrs); }; - }, - - // directive api - controller: 'esriMapController' + } }; });