Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
140 views
in Technique[技术] by (71.8m points)

javascript - Angular.js pass data from async service to scope

I have a service like

app.factory('geolocation', function ($rootScope, cordovaReady) {
    return {
        getCurrentPosition: cordovaReady(function (onSuccess, onError, options) {

            navigator.geolocation.getCurrentPosition(function () {
                var that = this,
                    args = arguments;

                if (onSuccess) {
                    $rootScope.$apply(function () {
                        onSuccess.apply(that, args);
                    });
                }
            }, function () {
                var that = this,
                    args = arguments;
                if (onError) {
                    $rootScope.$apply(function () {
                        onError.apply(that, args);
                    });
                }
            }, options);
        }),
        getCurrentCity: function (onSuccess, onError) {
            this.getCurrentPosition(function (position) {
                var geocoder = new google.maps.Geocoder();
                geocoder.geocode(options,function (results, status) {
                    var city = address_component.long_name;
                });
            });
        }
    }
});

And I want to do from a controller something like

function MainCtrl($scope, geolocation) {
   geolocation.getCurrentCity(function(city){
       $scope.city = city;
   });
};

The getCurrentPosition works fine and the city is determined too, however I don't know how to access the city in controller.

What happens? When getCurrentCity is called, it calles getCurrentPosition to determine the gps coords. This coords are passed as arguments to the onSuccess method right? So this is quite the same I want to do in the getCurrentCity method, but I don't know how. Ones the async geocoder retrieved the city, I want to apply the new data to the onSuccess method.

Any ideas?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are dealing with callbacks and asynchronous request. So you should use $q service. Just inject it in your service with $rootScope and cordovaReady dependency. And add the promises to your function like this

getCurrentCity: function () {
    var deferred = $q.defer(); 
    this.getCurrentPosition(function (position) {
      var geocoder = new google.maps.Geocoder();
      geocoder.geocode(options,function (results, status) {
        var city = address_component.long_name;
        $rootScope.$apply(function(){
          deferred.resolve(city);
        });
      });
    });
    return deferred.promise;
}

And in your controller, do the following to handle the promise.

function MainCtrl($scope, geolocation) {
   geolocation.getCurrentCity().then(function(result) {  //result === city
     $scope.city = result;
     //do whatever you want. This will be executed once city value is available
   });     
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...