【问题标题】:How can I use HTML5 geolocation in angularjs如何在 angularjs 中使用 HTML5 地理位置
【发布时间】:2014-06-04 19:44:25
【问题描述】:

如何在 angularjs 中使用 HTML5 地理位置?我可以使用 HTML5 获得它;但是如何将它传递给控制器​​中的 angularjs 范围?任何示例 jsfiddle 都会节省我的时间!

【问题讨论】:

    标签: javascript angularjs angularjs-directive geolocation angularjs-scope


    【解决方案1】:

    我建议将其抽象为一个服务,这样您的控制器就不会依赖于 window.navigator,并避免不必要地使用 $scope.$apply()。这是我在项目中使用的:

    angular.module('app', []).factory('geolocationSvc', ['$q', '$window', function ($q, $window) {
    
        'use strict';
    
        function getCurrentPosition() {
            var deferred = $q.defer();
    
            if (!$window.navigator.geolocation) {
                deferred.reject('Geolocation not supported.');
            } else {
                $window.navigator.geolocation.getCurrentPosition(
                    function (position) {
                        deferred.resolve(position);
                    },
                    function (err) {
                        deferred.reject(err);
                    });
            }
    
            return deferred.promise;
        }
    
        return {
            getCurrentPosition: getCurrentPosition
        };
    }]);
    

    然后我像这样在我的控制器中使用它:

    function captureUserLocation() {
        geolocationSvc.getCurrentPosition().then(onUserLocationFound);
    }
    

    【讨论】:

    • 这应该是答案,它促进了解耦并显示了对异步编程的良好使用。
    • 虽然这是一篇旧帖子,但我发现它对开始使用 geoLocation 很有帮助。想知道如何测试错误并且不了解上面的 onUserLocationFound 函数,它做了什么处理以及如何处理错误?
    • @HarveyMushman 该实现返回一个使用用户位置 (deferred.resolve(position)) 解析的承诺,因此您的处理程序将是接收该数据的函数,例如onUserLocationFound(position) { ... }。如果你想处理地理定位错误,你会像任何其他承诺一样使用catch
    【解决方案2】:

    你可以做点什么

    myApp.controller('fooCtrl', function($scope){
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position){
          $scope.$apply(function(){
            $scope.position = position;
          });
        });
      }
    })
    

    您需要执行 $scope.$apply 以在地理位置到达时触发摘要循环并更新所有观察者。

    【讨论】:

    • 你能帮我用jsfiddle吗?如果你不介意,我是 angularjs 的新手,还没有用过手表。如果没有,我不会介意:)
    • 如果你创建一个骨架 jsfiddle 或 plunkr 我可以填写,但你必须自己做一些工作
    • 注意你使用这个 sn-p 的步骤!在某些类型的浏览器中,这会返回安全警报,而在 Chrome(50+) 中,如果没有 https,则不支持 navigator.geolocation
    【解决方案3】:

    您可以使用ngGeolocation。它很简单,并且可以完成工作。

    angular.module('appName', ['ngGeolocation'])
        .controller('appCtrl', function($scope, $geolocation) {
             $geolocation.getCurrentPosition().then(function(position) {
                console.log(position, 'current position');
             });
        });
    

    【讨论】:

      【解决方案4】:

      由于 Firefox 的问题是当用户单击“不现在”、X 或外部提示框 (more here) 时提示网站需要访问您的位置时没有收到用户的反馈,下面是一个触发后备操作的小示例这个案例。 Plunker

      // GeoLocationService
      angular.module('myApp').factory('GeoLocationService', function($q, $window, $timeout) {
          var factoryObj = {};
      
          factoryObj.getPosition = function() {
              var deferred;
              var promiseTimeout = $timeout(function() {
                  deferred.reject(1); // return 1 if browser waited for user input for more than timeout delay
              }, 3000);
      
              deferred = $q.defer();
      
              if(!$window.navigator.geolocation) { // check if geoLocation is not supported by browser
                  $timeout.cancel(promiseTimeout);
                  deferred.reject(false); // return false if geoLocation is not supported
              }
              else { // geoLocation is supported
                  $window.navigator.geolocation.getCurrentPosition(function(position) {
                      $timeout.cancel(promiseTimeout);
                      return deferred.resolve(position);
                  }, function(error) {
                      $timeout.cancel(promiseTimeout);
                      return deferred.reject(error.code || 1);
                  });
              }
      
              return deferred.promise;
          };
      
          return factoryObj;
      });
      

      还有你的应用 js。

      // App
      var app = angular.module('myApp', []).controller('myCtrl', function($scope, $log, GeoLocationService) {
          $scope.position = {};
      
          GeoLocationService.getPosition().then(
              function(position) { // 
                  $scope.position = position;
                  $log.debug(position);
              },
              function(errorCode) {
                  if(errorCode === false) {
                      alert('GeoLocation is not supported by browser.');
                  }
                  else if(errorCode == 1) {
                      alert('User either denied GeoLocation or waited for long to respond.');
                  }
              }
          );
      });
      

      【讨论】:

      • 我不推荐这种方法。选择适合所有场景的超时持续时间是不可能的,我不想仅仅因为访问者没有足够快的回答而排除地理位置。相反,无论出于何种原因,我都会设计我的用户体验以适应没有用户的位置。如果你真的想要这种行为,我不会把它放在地理定位服务中;它应该进入使用该服务的控制器中。
      猜你喜欢
      • 2023-04-02
      • 2012-08-16
      • 2019-11-11
      • 2011-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-13
      • 1970-01-01
      相关资源
      最近更新 更多