我正在开发angularjs单页面应用程序,并且我正在尝试为应用程序构建一个映射系统。地图正在加载正常,但每当我尝试使用地理编码功能时,我都会收到错误 referenceError:Google未定义。
地图控制器
(function () {
'use strict';
angular
.module('CityWits')
.controller('mapCtrl', mapCtrl);
mapCtrl.$inject = ['$scope', '$http', 'mapApi', '$q'];
function mapCtrl($scope, $http, mapApi, $q){
var vm = this;
vm.setQuery = setQuery;
// todo: Switch this out with deals that are loaded depending on the radius of the map
getBranches();
function setQuery(query) {
console.log("business deal filter controller : query=" + query);
vm.query = query;
vm.focus = false;
}
function getBranches(){
$http.get('app/cwitsTestData/branchData.json').then(function(data){
vm.branches = sortBranches(data.data.branches);
$scope.$broadcast("branchesSorted", vm.branches);
});
}
}
function sortBranches(branches){
var locations, address, text;
locations = [];
for(var branch in branches){
address = branches[branch].address;
text = address.street_line1 + " " + address.city+ " " +address.state;
locations.push(text);
}
return locations;
}
})();
这是我写的处理api的谷歌工厂:
(function() {
'use strict';
angular
.module('CityWits')
.factory('mapApi', mapApi);
function mapApi () {
var mapApi = {}
var markers = [];
var geocoder;
var service;
mapApi.geocode = geocode;
mapApi.marker = marker;
mapApi.distance = distance;
return mapApi;
function geocode (addresses){
geocoder = new google.maps.Geocoder();
var coords = [];
if(geocoder){
for(var i in addresses){
geocoder.geocode( { 'address': addresses[i]}, function(results, status) {
if (status === 'OK') {
coords.push(results[0].geometry.location);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
}
}
function distance(start, end, method="DRIVING"){
service = new google.maps.DistanceMatrixService;
service.getDistanceMatrix({
origins: start,
destinations: end,
travelMode: method
}, function (status, response){
if(status ==! "OK"){
console.log("Error: "+status);
} else {
console.log("distance measured");
var result = {};
for(var i in response.rows){
result = response.rows[i].element;
}
return result;
}
});
}
function marker(positions, json){
if(markers.length > 0){
for(o in markers){
markers[o].setMap(null);
}
}
for(x in positions){
}
}
}
})();
最后这是启动api的指令:
(function () {
'use strict';
angular
.module('CityWits')
.directive('dealMap', dealMap);
dealMap.$inject = ['$timeout', '$http', 'mapApi'];
function dealMap($timeout, $http, mapApi){
var directive = {
link: link,
templateUrl: 'app/map/map.directive.html',
scope: {
deals: '=',
branches: '='
},
restrict: 'EA'
};
return directive;
function link(scope, element, attrs) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.defer = true;
script.src = "https://maps.googleapis.com/maps/api/js?key=AIzaSyB4RaOArTNm9C7crfutMVc0KkWIoQG-ZE0";
document.body.appendChild(script);
$timeout(function(){
scope.initialize();
}, 500);
// todo: Do stuff after deals are loaded based on map radius
scope.$on('branchesSorted', function(event, data) {
console.log('deals loaded');
console.log(data);
var points = mapApi.geocode(data);
console.log(points);
});
scope.initialize = function() {
scope.mapOptions = {
zoom: 8,
center: new google.maps.LatLng(22.649907498685803, 88.36255413913727)
};
scope.map = new google.maps.Map(document.getElementById('map'), scope.mapOptions);
};
console.log(scope);
}
}
})();
答案 0 :(得分:0)
显然,由于尚未加载Google Maps API,因此会发生此错误。
加载数据的时刻:
$http.get('app/cwitsTestData/branchData.json').then(function(data){
vm.branches = sortBranches(data.data.branches);
$scope.$broadcast("branchesSorted", vm.branches);
});
以及之后使用Geocoder
时,没有保证Google Maps API已在此时加载:
scope.$on('branchesSorted', function(event, data) {
console.log('deals loaded');
console.log(data);
var points = mapApi.geocode(data); //<--Google Maps API could be still not loaded at that moment
console.log(points);
});
因为Google地图库在您的示例中以异步方式加载
,如下所示:var script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.defer = true;
script.src = "https://maps.googleapis.com/maps/api/js?key=AIzaSyB4RaOArTNm9C7crfutMVc0KkWIoQG-ZE0";
document.body.appendChild(script);
我会提出以下解决方案。
让我们介绍以下服务来加载Google Maps API,创建地图并在准备就绪后通知:
.factory('googleMapsApi', function ($rootScope,$window, $q) {
return {
load: function (key) {
var deferred = $q.defer()
if ($window.google && $window.google.maps) {
deferred.resolve($window.google);
}
else {
var url = 'https://maps.googleapis.com/maps/api/js?callback=googleMapsLoad';
if (key) url += "&key=" + key;
var script = document.createElement('script');
script.type = 'text/javascript'
script.src = url;
$window.googleMapsLoad = function () {
deferred.resolve($window.google);
}
document.body.appendChild(script);
}
return deferred.promise;
},
createMap : function(scope,id,options){
var mapObject = new google.maps.Map(document.getElementById(id), options);
scope.$emit('google-maps-loaded',mapObject);
},
onMapReady : function(scope, ready){
var handler = $rootScope.$on('google-maps-loaded', function(evnt,data){ return ready(data);});
scope.$on('$destroy', handler);
}
}
})
然后可以通过指令的link
函数创建这样的地图:
link: function (scope, element, attributes) {
googleMapsApi.load(scope.key)
.then(function () {
var mapOptions = {
center: scope.center,
zoom: scope.zoom,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
googleMapsApi.createMap(scope,attributes.id,mapOptions);
});
}
并将数据加载到 controller 中,如下所示:
.controller('MyCtrl', function ($scope, googleMapsApi) {
googleMapsApi.onMapReady($scope, function(mapInst) {
console.log('Google Map is ready');
mapInst.data.loadGeoJson('https://storage.googleapis.com/mapsdevsite/json/google.json');
});
});