javascript - AngularJS + ArcGIS

标签 javascript angularjs dojo arcgis arcgis-js-api

我正在尝试使用 ArcGIS JavaScript API在 Angular 应用程序中。如我所见,它使用 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 

我的问题是如何正确地将 ArcGIS 功能注入(inject)到 Angular 应用程序中?

最佳答案

我认为对此的一种非常“AngularJS”风格的方法类似于以下内容。 (在这里摆弄http://jsfiddle.net/technicolorenvy/2Ke62/4/)

我喜欢使用 angular-ui-router,但这种方法也适用于 Angular 的 $routeProvider。这里的魔力在于 resolve 对象,它可以选择“等待”直到 promise 得到解决,然后再继续。

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;
                }
            }
        });
    });

正如您在上面看到的,我们有一个 map 状态,它有一个 resolve 属性。然后,您可以构建一个代表您的 ArcGIS/Dojo 依赖项的对象,并将其传递给您的 wish.loadDependencies(见下文)。

使用 q 我们将返回一个 promise ,一旦所有依赖项都通过 dojo 的 require

加载,该 promise 就会得到解决
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 中,您可以通过在 deps 对象中使用的键直接调用所有 ArcGIS/Dojo fns(就像您通常那样)这是在应用程序配置期间构建的,因为它们现在附加到 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, 197, 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,
            minDataValue: 0,
            maxDataValue: 100
        });

        layer.setRenderer(new w.ScaleDependentRenderer({
            rendererInfos: [{
                'renderer': renderer1,
                    'minScale': 50000000,
                    'maxScale': 10000000
            }, {
                'renderer': renderer2,
                    'minScale': 0,
                    'maxScale': 5000000
            }]
        }));

        $scope.map.addLayer(layer);
    });

演示上述代码的工作 fiddle ,可在此处找到 http://jsfiddle.net/technicolorenvy/2Ke62/4/

关于javascript - AngularJS + ArcGIS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17547399/

相关文章:

javascript - 将变量字符串值转换为 JavaScript 中的表达式

javascript - 如何在用户单击第二个下拉菜单时关闭第一个下拉菜单?

angularjs - 为什么 AngularJS 指令(属性等)在 WebStorm 8 中显示为 "invalid"?

javascript - 传单标记图标点击事件不起作用

javascript - 在全局变量中存储 Angular js响应时出现问题

javascript - 哪个是最适合测量报告 Web 应用程序的 javascript 小部件库?

javascript - 将原始 HTML 标签分配给 JavaScript 变量

javascript .replace 一个 html 标签不替换

Dojo DateTextBox 从周一开始

javascript - Dojo 教程 - 业务应用程序架构