Google Maps AngularJS具有多个地址

时间:2014-12-17 16:13:31

标签: javascript jquery angularjs google-maps angular-google-maps

我有一个使用AngularJS服务并使用Angular-Google-Maps的应用程序,我的地图上有多个标记,但我无法点击每个标记。允许点击的唯一标记是最后一个不允许我在打开窗口后关闭它的标记,或者如果我只有一个地址标记按预期工作。我想我已经接近但无法弄清楚我可能缺少什么来点击标记对所有这些都有效。关于我缺少什么或需要做什么不同的任何想法?

这是我页面上的标记。

<div ng-app="myMapApp" ng-controller="mapController">    
<ui-gmap-google-map center='map.center' zoom='map.zoom' options="options">        
    <ui-gmap-markers models="directoryMarkers" coords="'self'" icon="'icon'" click="'onClick'">
        <ui-gmap-windows show="show">
            <div ng-non-bindable>{{organization}}</div>
        </ui-gmap-window> 
    </ui-gmap-markers>
</ui-gmap-google-map>
</div>

myMapApp.js中的代码

var app = angular.module("myMapApp", ['uiGmapgoogle-maps', 'ngStorage']);

mapController.js中的代码

app.controller('mapController', function ($scope, Geocoder) {

$scope.map = { center: { latitude: 45, longitude: -73 }, zoom: 10 };

var hfValue = $("#ucDirectory_UcResults_hfResults");

$scope.directoryMarkers = [];

var createMarker = function (organization, address, latitude, longitude, i) {

    var ret = {
        latitude: latitude,
        longitude: longitude,
        address: address,
        organization: organization,
        show: false
    };

    ret.onClick = function () {
        console.log("Clicked!");
        ret.show = !ret.show;
    };

    ret["id"] = i;
    return ret;
};

var json = jQuery.parseJSON(hfValue[0].value);

var markers = [];
var i = 0;

var org;

for (var key in json) {
    if (json.hasOwnProperty(key)) {

        org = json[key].organization;



        if (json[key].address.length > 0) {

            Geocoder.geocodeAddress(json[key].address).then(function (data) {

            markers.push(createMarker(org, json[key].address, data.lat, data.lng, i))

            $scope.map.center.latitude = data.lat;
            $scope.map.center.longitude = data.lng;

            });

            i++;
        }
    }
}

$scope.directoryMarkers = markers;


});

geocoder-service.js中的代码

 * An AngularJS Service for intelligently geocoding addresses using Google's API. Makes use of
 * localStorage (via the ngStorage package) to avoid unnecessary trips to the server. Queries
 * Google's API synchronously to avoid `google.maps.GeocoderStatus.OVER_QUERY_LIMIT`.
 *
 * @author: benmj
 * @author: amir.valiani
 *
 * Original source: https://gist.github.com/benmj/6380466
 */

/*global angular: true, google: true, _ : true */

'use strict';

//angular.module('geocoder', ['ngStorage']).factory('Geocoder', function ($localStorage, $q, $timeout, $rootScope) {
app.factory('Geocoder', function ($localStorage, $q, $timeout, $rootScope) {
    var locations = $localStorage.locations ? JSON.parse($localStorage.locations) : {};

    var queue = [];

    // Amount of time (in milliseconds) to pause between each trip to the
    // Geocoding API, which places limits on frequency.
    var QUERY_PAUSE = 250;

    /**
     * executeNext() - execute the next function in the queue.
     *                  If a result is returned, fulfill the promise.
     *                  If we get an error, reject the promise (with message).
     *                  If we receive OVER_QUERY_LIMIT, increase interval and try again.
     */
    var executeNext = function () {
        var task = queue[0],
          geocoder = new google.maps.Geocoder();

        geocoder.geocode({ address: task.address }, function (result, status) {

            if (status === google.maps.GeocoderStatus.OK) {

                var parsedResult = {
                    lat: result[0].geometry.location.lat(),
                    lng: result[0].geometry.location.lng(),
                    formattedAddress: result[0].formatted_address
                };
                locations[task.address] = parsedResult;

                $localStorage.locations = JSON.stringify(locations);

                queue.shift();
                task.d.resolve(parsedResult);

            } else if (status === google.maps.GeocoderStatus.ZERO_RESULTS) {
                queue.shift();
                task.d.reject({
                    type: 'zero',
                    message: 'Zero results for geocoding address ' + task.address
                });
            } else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
                if (task.executedAfterPause) {
                    queue.shift();
                    task.d.reject({
                        type: 'busy',
                        message: 'Geocoding server is busy can not process address ' + task.address
                    });
                }
            } else if (status === google.maps.GeocoderStatus.REQUEST_DENIED) {
                queue.shift();
                task.d.reject({
                    type: 'denied',
                    message: 'Request denied for geocoding address ' + task.address
                });
            } else {
                queue.shift();
                task.d.reject({
                    type: 'invalid',
                    message: 'Invalid request for geocoding: status=' + status + ', address=' + task.address
                });
            }

            if (queue.length) {
                if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
                    var nextTask = queue[0];
                    nextTask.executedAfterPause = true;
                    $timeout(executeNext, QUERY_PAUSE);
                } else {
                    $timeout(executeNext, 0);
                }
            }

            if (!$rootScope.$$phase) { $rootScope.$apply(); }
        });
    };

    return {
        geocodeAddress: function (address) {
            var d = $q.defer();

            if (_.has(locations, address)) {
                d.resolve(locations[address]);
            } else {
                queue.push({
                    address: address,
                    d: d
                });

                if (queue.length === 1) {
                    executeNext();
                }
            }

            return d.promise;
        }
    };
});

1 个答案:

答案 0 :(得分:2)

顺便说一句,如果你没有同时打开很多窗口,你就不应该使用windows指令,而是使用window指令并将其定义为你的标记的兄弟。根据文档的建议。

但是要回答原始问题,这个plnkr会使用您的代码减去地理编码来生成带有窗口的标记。只需点击两次标记就可以到达您想要的位置,因为点击发生在值更改之前。

我认为要获得您想要的行为,它看起来更像是:

HTML:

<ui-gmap-google-map center='map.center' zoom='map.zoom' options="options">        
<ui-gmap-markers fit="true" models="directoryMarkers" coords="'self'" icon="'icon'" click="'onClick'">
</ui-gmap-markers>
<ui-gmap-window show="selected.show" coords="selected">
        <div>{{selected.organization}}</div>
</ui-gmap-window> 

控制器:

  $scope.map = {
    center: {
      latitude: 45,
      longitude: -73
    },
    zoom: 10
  };

  $scope.directoryMarkers = [];
  $scope.selected = null;

  var createMarker = function(latitude, longitude, i) {

    var ret = {
      latitude: latitude,
      longitude: longitude,
      organization: "Foo",
      show: false
    };

    ret.onClick = function() {
      console.log("Clicked!");
      $scope.selected = ret;
      ret.show = !ret.show;
    };

    ret["id"] = i;
    return ret;
  };

  var markers = [];

  var org;

  var coords = chance.coordinates().split(",");
  $scope.map.center.latitude = coords[0];
  $scope.map.center.longitude = coords[1];
  for (var i = 0; i < 20; i++) {
    coords = chance.coordinates().split(",");
    markers.push(createMarker(coords[0], coords[1], i));
  }

  $scope.directoryMarkers = markers;

在这个plnkr:http://plnkr.co/edit/rT4EufIGcjplgd8orVWu?p=preview

中可以看到哪些联系在一起