2013-01-15 18 views
20

Sorumu Angular Google grubunda this topic dayanmaktadır.
Arka uçtan alınan bazı temel verileri $ http kullanarak saklayan bir hizmet sunmak istiyorum, o zaman bu verileri bir kez almak zorundayım. gibiPromise and service'i birlikte kullan Angular

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

sorun söz zinciri userProvider biter ancak denetleyicisi, böylece kullanıcı Veri iade edilmemiştir çünkü bu denetleyici kullanmak ilk defa tanımlanmamış olmasıdır.

Böyle bir depolama hizmetini nasıl kullanabilirim ve verileri doğru şekilde nasıl verebilirim? Teşekkürler!

cevap

18

Sadece kendi sözlerinizi oluşturabilirsiniz. İşte değiştirilmiş kodu:

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

Güncelleme: @yohairosen aşağıda çözüm değil herkes için, birçok durumda büyük bir tanesidir. Bazı durumlarda, burada yaptığım gibi sadece başarılı sonucunu önbelleğe almak istiyoruz. Örneğin, bu isteğin bir başarısızlığı kullanıcının önce giriş yapması gerektiğini gösterirse, önbelleğe alınan arızayı iletmek için bir sonraki aramayı (muhtemelen giriş yaptıktan sonra) istemezdik. Yöntemin, her koşulda çağrıdan aramaya tutarlı bir şekilde tutarlı olmadığı durumlarda, bu yöntem daha iyidir; Diğer tüm durumlarda, @ yohairosen'in çözümü daha basit ve tavsiye edilir.

+0

Teşekkür Josh, çalışıyor! – Edward

+2

Harika çalışıyor. Eksik olabilecek tek şey, ilk arama veri alırken ek harici çağrıları engellemek için bir şeydir. – keyser

17

Kendi sözünü oluşturmak için biraz fazladan bir masraf var, köşeli $ http, sizin için bir tane oluşturuyor. Aradığınız şey önbellekleme ve http önbelleği geçirerek sizin için halledebilir: servis çağrısına göre doğru.

Yani basitçe böyle bir şey yapabilirsiniz:

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

    return { 
     getUser : getUser 
    } 
});