Моя цель:Цепные обещания/требуют в AngularJS
Построить AngularJS службу (MapService
), который инициализирует (MapService.initMap()
) 3-го партийного контроля (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);
Plunkr
https://plnkr.co/edit/LEhYqHVSpscTZ5kJCfyJ
Проблема:
Обещание, которое возвращает getMap()
, поэтому код в пределах MapService.getMap().then()
так и не был достигнут.
Когда я разрешаю обещание с некоторой тестовой строкой (self.deferred.resolve('test');
) в моем методе initMap()
, он работает.
Таким образом, я полагаю, что это проблема метода esriLoader.require(), который является еще одним обещанием, которое после require
связано с некоторыми зависимостями компонента карты.
Так что я в основном решаю обещание в рамках обещания. Я добавил код esriLoader в plunkr.
Что я делаю неправильно?
Используйте один метод 'initMap', который будет проверять, если карта инициализируется, то он возвращает экземпляр карты, в противном случае он будет инициализировать и затем вернуть экземпляр. Это не решит проблему. Просто совет для хорошего кода. – karaxuna
Учитывая, что 'esriLoader.require' уже возвращает обещание, вы должны [избегать отложенного антипаттера] (http://stackoverflow.com/q/23803743/1048572)! – Bergi