2013-07-16 11 views
11

को async सेवा से डेटा पास मैंAngular.js गुंजाइश

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

की तरह एक सेवा है और मैं

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

की तरह एक नियंत्रक कुछ से क्या करना चाहते हैं getCurrentPosition ठीक काम करता है और शहर है भी निर्धारित है, हालांकि मुझे नहीं पता कि नियंत्रक में शहर का उपयोग कैसे किया जाए।

क्या होता है? जब प्राप्त करें CurrentCity कहा जाता है, तो यह gps coords निर्धारित करने के लिए getCurrentPosition कहते हैं। इस कॉरपोरेशन को ऑनस्यूशन विधि पर तर्क के रूप में पारित किया गया है? तो यह वही है जो मैं getCurrentCity विधि में करना चाहता हूं, लेकिन मुझे नहीं पता कि कैसे। Async geocoder ने शहर को पुनर्प्राप्त किया, मैं नए डेटा को ऑनसेप विधि पर लागू करना चाहता हूं।

कोई विचार?

उत्तर

29

आप कॉलबैक और अतुल्यकालिक अनुरोध के साथ काम कर रहे हैं। तो आपको $q सेवा का उपयोग करना चाहिए। रूट्सस्कोप और कॉर्डोवा रेडी निर्भरता के साथ बस अपनी सेवा में इसे इंजेक्ट करें। और यह

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

की तरह और अपने नियंत्रक में अपने कार्य करने के लिए वादों जोड़ने के लिए, वादा को संभालने के लिए निम्न उपाय अपनाते हैं।

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

मेरी समस्या ठीक हुई, मेरे पास एक फ़िल्टर था जो लूप का कारण बन रहा था। –

+0

एक वचन के लिए $ स्कोप संपत्ति सेट करने के उपरोक्त नियंत्रक कार्यान्वयन में पहला दृष्टिकोण कोणीय 1.3 में और भी काम नहीं करता है।वचन अब और नहीं छोड़े गए हैं, इसलिए आपको दूसरे दृष्टिकोण (उस हैंडलर में $ स्कोप संपत्ति सेट करना) का उपयोग करना होगा – jbandi

+0

@jbandi: आपको लगता है कि कुछ बदल गया है। मुझे नहीं मिला कि सटीक परिवर्तन क्या है। क्या आप इसे मेरे लिए स्पष्टीकरण देते हैं? मैं तदनुसार जवाब अपडेट करूंगा। –

4

वहां परिणाम को संभालने के बजाय बस सेवा में अपनी ऑनसेफ विधि को कॉल करें।

getCurrentCity: function (onSuccess, onError) { 
    this.getCurrentPosition(function (position) { 
     var geocoder = new google.maps.Geocoder(); 
     geocoder.geocode(options, onSuccess); 
    }); 
} 

और अपने नियंत्रक में, परिणाम को पार्स करने और शहर में निर्दिष्ट करें:

function MainCtrl($scope, geolocation) { 
    geolocation.getCurrentCity(function(results, status){ 
     // Parse results for the city - not sure what that object looks like 
     $scope.city = results.city; 
    }); 
}; 
5

प्रयास करें इस

function MainCtrl($scope, geolocation) { 
    $scope.city = null; 
    geolocation.getCurrentCity(function(city){ 
     $scope.city = city; 
     if(!$scope.$$phase) { 
      $scope.$digest($scope); 
     } 
    }); 
}; 

कभी कभी, द्रष्टा हमेशा कहा जाता है नहीं है जब नियंत्रक instanciating, एक घटना को पचाने, अगर गुंजाइश चरण में नहीं है पर बाध्य करके, आप अपने इच्छित स्थान पर जा सकते हैं जाने के लिए, मुझे विश्वास है। अगर मुझे आपका प्रश्न समझ में नहीं आया तो मुझे बताएं।

ओह और मैं अगर मैं कोड properrly पढ़ पता नहीं है, लेकिन यह है कि आप बुला न होने पर अपने समारोह में onSuccess कॉलबैक लगता है: इस करके अपने getCurrentCity समारोह की जगह:

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; 
       if(typeof onSuccess === 'function') { 
        onSuccess(city); 
       } 
      }); 
     }); 
    } 
3

मुझे सही अगर मैं गलत हूं, लेकिन प्रस्तुत समाधान पूरी तरह से काम नहीं करेगा, क्योंकि नए कोणीय संस्करण (> 1.2 !?) अब स्वचालित रूप से $ q वादे को अनचाहे नहीं करते हैं।

इस प्रकार

:

$scope.city = geolocation.getCurrentCity(); 

हमेशा एक वादा किया जाएगा। तो आपको हमेशा उपयोग करना होगा:

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