我的目标:

构建一个AngularJS服务(MapService),该服务将初始化(MapService.initMap())第三方控件(Esri ArcGIS Map)并返回对我的地图(MapService.getMap())的引用,以便可以在所有控制器中使用它。



<!DOCTYPE html>
<html ng-app="app">
  <body ng-controller="MapController">


      <script data-require="[email protected]" data-semver="1.5.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
      <script defer type="text/javascript" src="//js.arcgis.com/4.0beta3/"></script>

      <script src="angular-esri-loader.js"></script>
      <script src="script.js"></script>
  </body>

</html>


Script.js:

(function(angular) {
    'use strict';

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

angular.module('app')
    .controller('MapController', function(esriLoader, $scope, MapService) {

        MapService.getMap().then(function (mapObj) {
            console.log("resolved!!!"); // this code is never reached
            alert('show map');
            $scope.map = mapObj;
        });

        MapService.initMap();

    });



angular.module('app')
    .service('MapService',  function($q, esriLoader) {
        this.deferred = $q.defer();

        this.getMap = function(){
            return this.deferred.promise;
        }
        var self = this;
        this.initMap = function() {

         // self.deferred.resolve('test'); // When I uncomment this line, the promise will be successfully resolved and the 'then' runs

            esriLoader.require([
                    'esri/Map',
                    'esri/widgets/Search',
                    'esri/widgets/Search/SearchViewModel'
                ]).then(function(esriModules){
                    var Map = esriModules[0];
                    var Search = esriModules[1];
                    var SearchViewModel = esriModules[2];

                    // Create the map
                    var map = new Map({
                        basemap: 'satellite'
                    });

                    console.log("resolve map"); // this code is reached, however, it still doesn't seem to correctly resolve the promise

                    self.deferred.resolve(map);

                });

        }

    });
})(angular);


普伦克

https://plnkr.co/edit/LEhYqHVSpscTZ5kJCfyJ

问题:

getMap()返回的承诺永远不会被解决,因此MapService.getMap().then()中的代码永远不会到达。

当我在我的self.deferred.resolve('test');方法中使用一些测试字符串(initMap())来解决诺言时,它就可以工作。

所以我想这是'esriLoader.require()'方法的问题,这是在require映射组件的某些依赖项之后解决的另一个承诺。

所以我基本上是在诺言中解决诺言。我将esriLoader的代码添加到了plunkr。

我究竟做错了什么?

最佳答案

问题在于Map实现了某种Promise接口。我建议检查文档。您可以通过将地图包装到一个对象中来解决问题:

var map = {
  map: new Map({
    basemap: 'satellite'
  })
};

console.log("resolve map"); // this code is reached

self.deferred.resolve(map);


正如其他人已经建议的那样,最好是调用MapService.initMap().then而不是同时调用两个方法和创建自己的Promise。而不是使用地图来解决问题,而是返回(包装的)地图:

        this.initMap = function() {

      //self.deferred.resolve('test'); // When I uncomment this line, the promise will be successfully resolved and the 'then' runs

        return esriLoader.require([
                'esri/Map',
                'esri/widgets/Search',
                'esri/widgets/Search/SearchViewModel'
            ]).then(function(esriModules){
                var Map = esriModules[0];
                var Search = esriModules[1];
                var SearchViewModel = esriModules[2];

                // Create the map
                var map = new Map({
                    basemap: 'satellite'
                });

                console.log("resolve map"); // this code is reached

                return {map: map};


            });

09-06 05:20