在服务AngularJs中修改$ scope [英] Modify $scope from within a service AngularJs

查看:74
本文介绍了在服务AngularJs中修改$ scope的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm developing an application for geolocalization based on Gmaps Api. The thing is that for adding new markers by user events I've made a service that simple add a listener to the map events and add markers when its clicked. The issue is that I can't find a way to modify some $scope properties from within the service. Here is the service that i've wrote:

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

                }
            );
        }
    }
});

如何返回e.latLng值,并在该值中设置一些$ scope.property?

How can I return de e.latLng value and with that value set some $scope.property ?

推荐答案

正如@Ajaybeniwal所说,您不应该在控制器外部触摸示波器.您可以更改 addListener 使其接受回调:

As @Ajaybeniwal said, you shouldn't touch the scope outside a controller. You could change addListener so it accepts a callback:

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

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

Now you can use it like this inside your controller:

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

您还可以使用promise而不是回调:

You could also use a promise instead of a callback:

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

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

And then your controller would look like this:

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

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

Promises have an advantage over callbacks: you can bind them directly to a view and Angular will render the correct value as soon as it becomes available. Check out this post for more information on that matter.

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

Last but not least, please notice that you need to call $rootScope.$apply() in both cases so Angular triggers a digest cycle and everything gets processed correctly. That's required because Angular knows nothing about google.maps.event.addListener and it won't get notified when the gmaps callback is executed.

这篇关于在服务AngularJs中修改$ scope的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆