广播时或加载视图时的角度?

时间:2014-04-10 14:27:51

标签: angularjs

我有一个简单的服务,它获取设备的gps位置并广播它:

还有一个默认位置。

service('currentPosition', function($rootScope){
        //default current position
        var myLocation = {lat: 59.3325800, long: 18.0649000}
        $rootScope.$broadcast('location', myLocation)

        if ("geolocation" in navigator) {
            navigator.geolocation.getCurrentPosition(function(position) {
                myLocation.lat = position.coords.latitude;
                myLocation.long = position.coords.longitude;
                $rootScope.$broadcast('location', myLocation)
            });
        }
        return{
            getMyLocation: function(){
                return myLocation;
            }
        }
    }).

在我的应用程序的几个视图中,我想添加一个监听器来更改位置。我还想在加载视图时获取值。我继续写下这样的话:

$scope.myLocation = currentPosition.getMyLocation();
$scope.$on('location', function(scope,myLocation){
    $scope.myLocation = myLocation;
});

在我的几个控制器和指令中。有一个更好的方法吗?例如,通过捕捉之前的广播。

1 个答案:

答案 0 :(得分:0)

当您在控制器中将myLocation对象的引用从服务传递到$scope.myLocation时,它们正在使用相同的对象,您不需要使用$ broadcast(或任何获取更新的其他通知系统。

演示http://plnkr.co/edit/PU3HyCx9YZybeADmv13I?p=preview

该服务将首先记录更新的myLocation对象,然后在一小段延迟后,控制器将记录其myLocation对象。

您会注意到两者都记录了更新后的对象。

这种情况下的问题是ui没有更新。这是因为navigator.geolocation.getCurrentPosition的回调发生在“Angular世界之外”,这意味着$ digest循环不会被触发,更改也不会反映在DOM中。

来自documentation

  

$ apply()用于从外部执行角度表达式   角度框架。 (例如,来自浏览器DOM事件,   setTimeout,XHR或第三方库)。因为我们正在呼唤   我们需要执行适当范围生命周期的角度框架   异常处理,执行手表。

在你的情况下:

if ("geolocation" in navigator) {
  navigator.geolocation.getCurrentPosition(function(position) {

    $rootScope.$apply(function() {
      myLocation.lat = position.coords.latitude;
      myLocation.long = position.coords.longitude;
    });
  });
}

演示http://plnkr.co/edit/hsN5xIPgtTDahyvpti0E?p=preview