我试图在Angular应用程序中使用
ArcGIS JavaScript API.我看到,它使用Dojo.所以,我正在尝试从Angular指令初始化ArcGIS,如下所示:
link: function (scope,element,attrs) { dojo.require('esri.map'); var init = function () { console.log('dojo is ready'); var map = new esri.Map("map-container",{ center: [-111.3797,56.7266 ],zoom: 16,basemap: "streets" }); map.enableScrollWheelZoom() }; dojo.addOnLoad(init); }
看起来这样不是100%正确,因为当我尝试通过滚动鼠标滚轮缩放,我得到这个错误:
Uncaught TypeError: Cannot call method 'apply' of null
我的问题是如何在Angular应用程序中注入ArcGIS功能?
解决方法
我认为一个非常“AngularJS”风格的方法就像这样. (小提琴
http://jsfiddle.net/technicolorenvy/2Ke62/4/)
我喜欢使用角ui路由器,但这种方法也可以与Angular的$routeProvider一起工作.这里的魔法是在解决方案的对象中,可以选择“等待”,直到承诺得到解决,然后继续.
angular.module('webApp',['ui.router']) // module (app) config .config(function ($stateProvider,$urlRouterProvider) { $urlRouterProvider.otherwise('/map'); $stateProvider.state('map',{ url: '/map',template: '<div id="map"></div>',controller: 'MapCtrl',resolve: { promiSEObj: function ($q,$rootScope,wish) { var deferred = $q.defer(),deps = { Map: 'esri/map',FeatureLayer: 'esri/layers/FeatureLayer',InfoTemplate: 'esri/InfoTemplate',SimpleFillSymbol: 'esri/symbols/SimpleFillSymbol',SimpleRenderer: 'esri/renderers/SimpleRenderer',SimpleMarkerSymbol: 'esri/symbols/SimpleMarkerSymbol',ScaleDependentRenderer: 'esri/renderers/ScaleDependentRenderer',Color: 'dojo/_base/Color' }; wish.loadDependencies(deps,function () { deferred.resolve(); if (!$rootScope.$$phase) { $rootScope.$apply(); } }); return deferred.promise; } } }); });
如上所述,我们有一个地图状态,具有解决方案.然后,您可以构建一个表示ArcGIS / Dojo依赖关系的对象,并将其传递给您的wish.loadDependencies(见下文).
使用q,我们将返回一个承诺,一旦所有依赖关系通过dojo的需求加载就解决
angular.module('webApp') // service that deals w/ our dojo require .service('wish',function () { // it's not require... it's a wish? var wish = {}; function _loadDependencies(deps,next) { var reqArr = _.values(deps),keysArr = _.keys(deps); // use the dojo require (required by arcgis + dojo) && save refs // to required obs require(reqArr,function () { var args = arguments; _.each(keysArr,function (name,idx) { wish[name] = args[idx]; }); next(); }); } return { loadDependencies: function (deps,next) { _loadDependencies(deps,next); },get: function () { return wish; } }; });
之后,在您的MapCtrl中,您可以直接(通常情况下)调用所有ArcGIS / Dojo fns,通过在app config中构建的deps对象中使用的键,因为它们现在附加到由wish.get().
以下是此处找到的示例的修改版本(https://developers.arcgis.com/en/javascript/jssamples/renderer_proportional_scale_dependent.html)
angular.module('webApp') // our map controller .controller('MapCtrl',function ($rootScope,$scope,wish) { var w = wish.get(),greenFill = new w.Color([133,197,133,0.75]),greenOutline = new w.Color([133,0.25]),layer,markerSym,renderer1,renderer2,CROPS_URL = 'http://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/USA_County_Crops_2007/FeatureServer/0'; $scope.map = new w.Map('map',{ center: [-98.579,39.828],zoom: 4,basemap: 'gray' }); layer = new w.FeatureLayer(CROPS_URL,{ outFields: ['STATE','COUNTY','M086_07','AREA'],infoTemplate: new w.InfoTemplate('${COUNTY},${STATE}','<div style="font: 18px Segoe UI">The percentage of the area of the county that represents farmland is <b>${M086_07}%</b>.</div>') }); layer.setDefinitionExpression('AREA>0.01 and M086_07>0'); markerSym = new w.SimpleMarkerSymbol(); markerSym.setColor(greenFill); markerSym.setOutline(markerSym.outline.setColor(greenOutline)); renderer1 = new w.SimpleRenderer(markerSym); renderer1.setProportionalSymbolInfo({ field: 'M086_07',minSize: 1,maxSize: 10,minDataValue: 0,maxDataValue: 100 }); //for the second renderer increase the dot sizes and set a backgroundFillSymbol renderer2 = new w.SimpleRenderer(markerSym); renderer2.setProportionalSymbolInfo({ field: 'M086_07',minSize: 5,maxSize: 15,maxDataValue: 100 }); layer.setRenderer(new w.ScaleDependentRenderer({ rendererInfos: [{ 'renderer': renderer1,'minScale': 50000000,'maxScale': 10000000 },{ 'renderer': renderer2,'minScale': 0,'maxScale': 5000000 }] })); $scope.map.addLayer(layer); });
工作小提琴演示了上述代码,在这里找到了http://jsfiddle.net/technicolorenvy/2Ke62/4/