我有$ scope.contacts与各种客户及其地址。我想遍历所有地址,将它们发送到google API并附加lat / lng以便以后在Google地图中使用。
多数民众赞成我到目前为止:
//Get already the Geodata of the selected GroupContacts
for (var p = 0; p < $scope.contacts.length;p++) {
var street = $scope.contacts[p].address;
var zip = $scope.contacts[p].postcode;
var city = $scope.contacts[p].city;
vermittlungService.getGoogleData(street,zip,city).then(function(response){
$rootScope.contacts[p].lat = response.data.results[0].geometry.location.lat;
$rootScope.contacts[p].lng = response.data.results[0].geometry.location.lng; //attach to the $scope
});
console.log($scope.contacts);
};
据我所知,异步调用中的[p]值已经改变了值,所以我无法将正确的lat / lng附加到联系人。我得到错误“:在控制台中无法读取未定义的属性'1'。
如何在循环中等待数据到达然后继续。
谢谢!编辑:这是我获得的Google数据服务
//Fetch Google API from Adress - Returns geoDataObject
this.getGoogleData = function(street,zip,city) {
return $http.get('https://maps.googleapis.com/maps/api/geocode/json?address= ' + street + '+' + zip + '+' + city + APIKEY)
.then(function(response) {
return response;
})
};
解决方案:我需要将逻辑包装在一个函数中。然后它的作品!
for (var p = 0; p < $scope.contacts.length;p++) {
(function(p) {
setTimeout(function() {
var street = $scope.contacts[p].address;
var zip = $scope.contacts[p].postcode;
var city = $scope.contacts[p].city;
vermittlungService.getGoogleData(street,zip,city,apiKey).then(function(response){
$rootScope.contacts[p].lat = response.data.results[0].geometry.location.lat;
$rootScope.contacts[p].lng = response.data.results[0].geometry.location.lng; //attach to the $scope
}, function(error){
console.log(error);
});
}, 250*p);
})(p);
});
您是否尝试过匿名函数的包装过程?
for (var p = 0; p < $scope.contacts.length;p++) {
!function() {
var street = $scope.contacts[p].address;
var zip = $scope.contacts[p].postcode;
var city = $scope.contacts[p].city;
vermittlungService.getGoogleData(street, zip, city).then(function(response) {
$rootScope.contacts[p].lat = response.data.results[0].geometry.location.lat;
$rootScope.contacts[p].lng = response.data.results[0].geometry.location.lng;
});
console.log($scope.contacts);
}();
};
您是否尝试过$ q来解析服务http调用中的promise,然后为该函数设置超时? (我相信谷歌地图api将通话次数限制为每秒四次,所以你要使用250毫秒)。
所以你的服务电话看起来像:
this.getGoogleData = function(street,zip,city,apiKey) {
var deferred = $q.defer();
$http.get('https://maps.googleapis.com/maps/api/geocode/json?address=' + street + '+' + zip + '+' + city +'&key=' + apiKey)
.then(function(response) {
deferred.resolve(response);
}, function(reason) {
deferred.reject(reason);
});
return deferred.promise;
};
在您的联系人列表中迭代您的一系列调用:
for (var p = 0; p < $scope.contacts.length;p++) {
(function(p) {
setTimeout(function() {
var street = $scope.contacts[p].address;
var zip = $scope.contacts[p].postcode;
var city = $scope.contacts[p].city;
vermittlungService.getGoogleData(street,zip,city,apiKey).then(function(response){
$rootScope.contacts[p].lat = response.data.results[0].geometry.location.lat;
$rootScope.contacts[p].lng = response.data.results[0].geometry.location.lng; //attach to the $scope
}, function(error){
console.log(error);
});
}, 250*p);
})(p);
});