0

我有一个使用 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;
        }
    };
});
4

1 回答 1

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

于 2014-12-17T17:23:48.867 回答