谷歌地图和异步javascript

Google maps and asynchronous javascript

本文关键字:javascript 异步 谷歌地图      更新时间:2023-09-26

在我的控制器中,我有这个函数来获取地址的坐标:

function get_coor(city, callback)
{
    var geocoder = new google.maps.Geocoder();
    geocoder.geocode( { "address": city }, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
            var location = results[0].geometry.location;
            callback(location.lat(), location.lng());
            }
            else
{
            callback(); // callback for error
    }
            });
            }

这样做效果很好,并输出正确的纬度:

get_coor('Amsterdam', function(lat, lng) {
    console.log('here is my lat:' + lat);
});

我想在我的谷歌地图中使用这些坐标,所以我把它做成这样:

get_coor('Amsterdam', function(lat, lng) {
    $scope.map = {center: {latitude: lat, longitude: lng }, zoom: 4 };
    $scope.options = {scrollwheel: false};
    $scope.marker = {
        coords: {
            latitude: lat,
            longitude: lng
        },
        show: false,
        id: 0
    };
    $scope.windowOptions = {
        visible: false
    };
    $scope.onClick = function() {
        $scope.windowOptions.visible = !$scope.windowOptions.visible;
    };
    $scope.closeClick = function() {
        $scope.windowOptions.visible = false;
    };
});

地图居中正确,因此$scope.map = {center: {latitude: lat, longitude: lng }, zoom: 4 };似乎工作正常,但标记位于其默认位置,而不是阿姆斯特丹。当我查看源时,标记的坐标是正确的坐标。

我的猜测是,它与异步javascript有关,但我对此非常陌生。。。有谁能帮忙吗?

更新:

刷新页面会将标记放在正确的位置,但在第一次加载时它会一直存在。

由于geocoder.geocode函数异步执行,并且ui-gmap-marker子指令,因此在这种情况下应该显式调用$apply()

$scope.marker = {
      coords: {
        latitude: location.lat(),
        longitude: location.lng()
      },
      title: 'Amsterdam',
      show: true,
      id: 1
};

$scope.$apply();

工作示例

var appMaps = angular.module('appMaps', ['uiGmapgoogle-maps']);
appMaps.controller('mainCtrl', function ($scope, uiGmapGoogleMapApi, uiGmapIsReady) {
  $scope.windowOptions = {
    visible: false
  };
  $scope.onClick = function () {
    $scope.windowOptions.visible = !$scope.windowOptions.visible;
  };
  $scope.closeClick = function () {
    $scope.windowOptions.visible = false;
  };
  $scope.options = { scrollwheel: false };
  $scope.map = { center: { latitude: 30, longitude: 0 }, zoom: 4 };
  var resolveAddress = function (address, callback) {
    var geocoder = new google.maps.Geocoder();
    geocoder.geocode({ "address": address }, function (results, status) {
      if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
        var location = results[0].geometry.location;
        callback(location);
      }
      else {
        callback(null);
      }
    });
  }
  uiGmapGoogleMapApi.then(function (gapi) {
    resolveAddress('Amsterdam', function (location) {
      $scope.$apply(function () {
        $scope.map.center = { latitude: location.lat(), longitude: location.lng() };
        $scope.marker = {
          coords: {
            latitude: location.lat(),
            longitude: location.lng()
          },
          title: 'Amsterdam',
          show: true,
          id: 1
        };
      });
    });
  });
});
.angular-google-map-container {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
}
<script src="https://code.angularjs.org/1.3.14/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
<script src="http://rawgit.com/angular-ui/angular-google-maps/2.0.X/dist/angular-google-maps.js"></script>
<div ng-app="appMaps" id="map_canvas" ng-controller="mainCtrl">
	<ui-gmap-google-map center="map.center" zoom="map.zoom" draggable="true" options="options" bounds="map.bounds">
		<ui-gmap-marker idkey="marker.id" coords="marker.coords" options="marker.options" click="onClick()" events="marker.events" />
	</ui-gmap-google-map>
</div>