2013-01-15 38 views
20

में एक साथ वादा और सेवा का उपयोग करें मेरा प्रश्न कोणीय Google समूह में this topic पर आधारित है।
मैं एक ऐसी सेवा प्रदान करना चाहता हूं जो बैकएंड से $ http के माध्यम से कुछ बुनियादी डेटा पुनर्प्राप्त करे, तो मुझे केवल एक बार उन डेटा को लाने की आवश्यकता है। जैसे,कोणीय

var load = function() { 
    return $http.get(...).then(function(data) { 
     return data.user; 
    }); 
}; 

module.factory("userProvider", function() { 
    var user; 
    var getUser = function() { 
     if(!user) { 
      load().then(function(data) { 
       user = data; 
      }); 
     } 
     return user; 
    }; 
    return { 
     getUser : getUser 
    } 
}); 

module.controller("UserController", ["userProvider", function UserController("userProvider") { 
    var user = userProvider.getUser(); 
    // do something with user 
}]); 

समस्या यह है कि वादा श्रृंखला userProvider में समाप्त होता है, लेकिन नियंत्रक में नहीं है, तो उपयोगकर्ता पहली बार मैं इस नियंत्रक के बाद से डेटा नहीं दिया नहीं किया गया है का उपयोग अपरिभाषित है।

मैं ऐसी स्टोरेज सेवा का उपयोग कैसे कर सकता हूं और डेटा को सही तरीके से वापस कर सकता हूं? धन्यवाद!

उत्तर

18

आप अपना खुद का वादा बना सकते हैं। यहाँ संशोधित कोड है:

module.factory("userProvider", function($q) { 
    // A place to hold the user so we only need fetch it once. 
    var user; 

    function getUser() { 
    // If we've already cached it, return that one. 
    // But return a promise version so it's consistent across invocations 
    if (angular.isDefined(user)) return $q.when(user); 

    // Otherwise, let's get it the first time and save it for later. 
    return whateverFunctionGetsTheUserTheFirstTime() 
    .then(function(data) { 
     user = data; 
     return user; 
    }); 
    }; 

    // The public API 
    return { 
    getUser: getUser() 
    }; 
}); 

अद्यतन: @yohairosen से नीचे समाधान कई परिस्थितियों के लिए एक महान एक है, लेकिन सभी के लिए नहीं। कुछ परिस्थितियों में, हम केवल सफल परिणाम कैश करना चाहते हैं, जैसा कि मैंने यहां किया है। यदि, उदाहरण के लिए, इस अनुरोध की विफलता से संकेत मिलता है कि उपयोगकर्ता को पहले लॉग इन करने की आवश्यकता है, तो हम कैश विफलता देने के लिए अगली कॉल (संभवतः लॉग इन करने के बाद) नहीं चाहते हैं। ऐसे मामलों में जहां विधि सभी परिस्थितियों में कॉल-टू-कॉल से जरूरी नहीं है, यह विधि बेहतर है; अन्य सभी मामलों में, @ योहेरसेन का समाधान सरल और अनुशंसित है।

+0

धन्यवाद जोश, यह काम करता है! – Edward

+2

महान काम करता है। एकमात्र चीज जो गायब हो सकती है वह अतिरिक्त बाहरी कॉल को रोकने के लिए कुछ है जबकि पहली कॉल डेटा ला रही है। – keyser

17

यह अपना स्वयं का वादा बनाने के लिए एक ओवरहेड है, कोणीय का $ http वैसे भी आपके लिए एक बनाता है। आप जो खोज रहे हैं वह कैशिंग पास कर रहा है और http कैश पास करके इसे आपके लिए संभाल सकता है: सेवा कॉल के लिए सच है।

तो आप बस कुछ इस तरह कर सकते हैं:

module.factory("userProvider", function() { 
    var getUser = function() { 
    return $http.get(..., {cache:true}).then(function(data) { 
     return data.user; 
    }); 

    return { 
     getUser : getUser 
    } 
}); 
संबंधित मुद्दे