1

我正在开发一个基于 Gmaps Api 的地理定位应用程序。问题是,为了通过用户事件添加新标记,我创建了一个服务,该服务可以简单地向地图事件添加侦听器并在单击时添加标记。问题是我找不到从服务中修改某些 $scope 属性的方法。这是我写的服务:

climbingApp.factory('Markers', function(){
    return {
        addListener: function() {
            google.maps.event.addListener(
                map,
                'click',
                 function( e ) {
                    var marker = new google.maps.Marker({
                        position: e.latLng,
                        map: map
                    });

                }
            );
        }
    }
});

如何返回 de e.latLng 值并使用该值设置一些 $scope.property ?

4

1 回答 1

11

正如@Ajaybeniwal 所说,您不应该触摸控制器之外的范围。您可以进行更改addListener,使其接受回调:

climbingApp.factory('Markers', function($rootScope) {
    return {
        addListener: function(callback) {
            google.maps.event.addListener(map, 'click', function(e) {
                $rootScope.$apply(function() { callback(e); });
            });
         }
    }
});

现在您可以在控制器中像这样使用它:

Markers.addListener(function(e) {
    $scope.model.position = e.latLng;
});

你也可以使用 promise 而不是回调:

climbingApp.factory('Markers', function($rootScope, $q) {
    return {
        addListener: function() {
            var deferred = $q.defer();
            google.maps.event.addListener(map, 'click', function(e) {
                $rootScope.$apply(function() { deferred.resolve(e); });
            });
            return deferred.promise;
         }
    }
});

然后您的控制器将如下所示:

Markers.addListener().then(function(e) {
    $scope.model.position = e.latLng;
});

Promise 比回调有一个优势:您可以将它们直接绑定到视图,Angular 将在它可用时立即呈现正确的值。查看这篇文章以获取有关此问题的更多信息。

最后但同样重要的是,请注意您需要$rootScope.$apply()在这两种情况下都调用,以便 Angular 触发一个摘要循环并正确处理所有内容。这是必需的,因为 Angular 对此一无所知,google.maps.event.addListener并且在执行 gmaps 回调时不会收到通知。

于 2013-09-25T19:54:44.617 回答