0

У меня есть приложение, которое использует услугу AngularJS и использует Angular-Google-Maps, и я получаю несколько маркеров на своей карте, но я не могу получить щелчок по каждому маркеру для работы. Единственным маркером, который позволяет клик, является последний, который не позволяет закрыть его после открытия окна, или если у меня есть только один адрес, маркер работает так, как ожидалось. Я думаю, что я близок, но не могу понять, чего я могу потерять, чтобы щелкнуть по маркерам для всех. Любые идеи о том, что мне не хватает или нужно делать по-другому?Google Maps AngularJS с несколькими адресами

Это разметка на моей странице.

<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; 


}); 

Код в геокодера-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; 
     } 
    }; 
}); 

ответ

2

В качестве в стороне, если у вас нет большого количества окон, открытых на th В то же время вы не должны использовать директиву windows, вместо этого используйте директиву окна и определяйте ее как родной для своих маркеров. Как рекомендовано в документации.

Но для ответа на исходный вопрос этот 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

+0

Yip У меня была такая же проблема, и это было потому, что я использовал «окна» вместо «окна» ... потратил полдня на эту проблему – cfl