У меня есть странная проблема с JavaScript Geocode Api из Google Maps в AngularJS.Google Maps Geocode AngularJS игнорирует обратный вызов
Прежде всего, я сделал некоторые исследования, и я выяснил, что мне нужно использовать функцию обратного вызова javascript для получения форматированного адреса из координаты.
Я реализовал функцию обратного вызова, как это:
"use strict";
var getParcelApp = angular.module("getParcelApp", []);
function getStartAddress(latlng, callback) {
var geocoder = new google.maps.Geocoder;
geocoder.geocode({ 'location': latlng }, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
callback(results[2].formatted_address); // HERE THE CALLBACK
}
});
};
var GetParcelAppController = function($scope, $http) {
$http.get("/umbraco/surface/ParcelSurface/GetLatLngParcel")
.success(function(result) {
$scope.coordinates = result;
$scope.getStartCoordinate();
})
.error(function(data) {
console.log(data);
});
$scope.getStartCoordinate = function() {
var latlng;
$scope.listOfCoordinates = [];
for (var i = 0; i < $scope.coordinates.length; i++) {
latlng = { lat: $scope.coordinates[i].Latitude, lng: $scope.coordinates[i].Longitude };
getStartAddress(latlng, function(formattedAddress) {
console.log(formattedAddress); // HERE formattedAddress WORKS
var coordinate = {
id: $scope.coordinates[i].Id,
waypointId: $scope.coordinates[i].WaypointId,
latitude: $scope.coordinates[i].Latitude,
longitude: $scope.coordinates[i].Longitude,
address: formattedAddress // HERE formattedAddress ISN'T WORKING
};
$scope.listOfCoordinates.push(coordinate);
});
}
console.log($scope.listOfCoordinates);
};
};
getParcelApp.controller("getParcelAppCtrl", GetParcelAppController);
Как вы можете видеть, что я хочу массив координат объектов. Но я действительно не знаю, почему console.log показывает правильный результат, а массив заполняется пустым?
Консоль Firefox показывает следующее:
- Массив:
- Array [] getParcelController.js: 45: 9
- отформатированные адреса:
- Mitte, Berlin, Deutschland getParcelController.js: 34: 17
- Иннерштадт, Кельн, Германия getParcelController.js: 34: 17
- Альтштадт-Леэль, München, Deutschland getParcelController.js: 34: 17
- Митте, Berlin, Deutschland getParcelController.js: 34: 17
- Innenstadt, Köln, Deutschland getParcelController.js: 34: 17
У вас есть идея, почему журнал консоли работает правильно, а функция массива - нет? Если я напишу функцию массива вне функции обратного вызова и без адрес: массив создан.
Чтобы быть более детальными:
Я хочу показать отформатированные адреса координат в выбранном раскрывающемся списке. Это определяется в HTML файл, как
<select id="getParcel" class="form-control"></select>
и я редактировал getStartAddress вызов вроде следующего:
$scope.getStartCoordinate = function() {
var latlng;
var selectBox = document.getElementById("getParcel");
$scope.listOfCoordinates = [];
for (var i = 0; i < $scope.coordinates.length; i++) {
latlng = { lat: $scope.coordinates[i].Latitude, lng: $scope.coordinates[i].Longitude };
getStartAddress(latlng, function(formattedAddress) {
var coordinate = {
id: $scope.coordinates[i].Id,
waypointId: $scope.coordinates[i].WaypointId,
latitude: $scope.coordinates[i].Latitude,
longitude: $scope.coordinates[i].Longitude,
address: formattedAddress
};
$scope.listOfCoordinates.push(coordinate);
console.log($scope.listOfCoordinates);
var selectElement = document.createElement("option");
selectElement.textContent = coordinate.address;
selectElement.value = coordinate.address;
selectBox.appendChild(selectElement);
});
}
};
Я действительно не специалист в JavaScript, но в моем понимании функции в getStartAddress тогда вызывается при получении данных обратного вызова? Таким образом, выпадающее окно выбора должно заполняться адресами, когда обратный вызов завершен, не так ли?
Поскольку 'getStartAddress' является' функция asynchronous' и вы регистрируете '$ scope.listOfCoordinates', прежде чем она получает данные (и толкнул его в массив). Вы должны делать все, что вы делаете внутри обратного вызова. Почему Async JS-программирование «не работает», вероятно, является одним из наиболее распространенных вопросов о SO. – Adam
Я знаю, что geocoder.geocode является асинхронной функцией, потому что я использую функцию обратного вызова в 'getStartAddress'. Но я не ожидал, что 'function (formattedAddress)' также является асинхронным? – Hardstyl3R
'function (formattedAddress)' является обратным вызовом функции async - он запускается только после того, как данные были извлечены. – Adam