2015-09-28 109 views
1

我剛剛開始學習angularjs,而且我已經花了4個小時來處理這個問題,但我仍然不知道什麼是錯的。返回意外數據的服務

我有一個服務從服務器獲取一些數據。

Service.js

(function() { 
    "use strict"; 
    angular.module('appName') 
     .service('MyService', function($http, $q, $location) {   
      var service = this; 
      service.data = false; 

      var deferred = $q.defer(); 

      //makes the api call to get that data 
      service.load = function() { 
      $http({ 
       method: 'GET', 
       url:'/url', 
       headers: { 'Content-type': 'application/json' }, 
       cache: false 
      }) 
      .then(function(response) { 
       service.data = response.data; 
       deferred.resolve(service.data); 
      },function() { 
       deferred.reject("Failed to get data"); 
      }); 

      return deferred.promise; 
      }; 

      //checks if the data has already been loaded. If not, load it... 
      service.loaded = function() {    
      if (!service.data) { 
       service.load() 
       .then(function(response) { 
        deferred.resolve(response); 
       }, 
       function(response) { 
        deferred.reject("Failed to load data"); 
       } 
      ); 
      } 
      else { 
       console.log('Already have data'); 
      } 

      return deferred.promise; 
      }; 

      //reset the data (for when we log out) 
      service.destroy = function() { 
      service.data = false; 
      }; 


     return { 
      loaded: service.loaded, 
      destroy: service.destroy, 
      getStuff: function() { 
      return service.data.stuff; 
      } 
     }; 

    }); 
})(); 

在我的控制,我把這樣的

Controller.js

(function() { 
    "use strict"; 
    angular.module('appName') 
     .controller('MyController', function($scope, $http, MyService) { 
      var controller = this; 

      $scope.stuff = []; 

      MyService.loaded() 
         .then(
         function(response) { 
          $scope.stuff = MyService.getStuff(); 
          controller.init(); 
         }, 
         function(response) { 
          console.log('Error', 'Could not get customers'); 
         }); 


      controller.init = function() { 
       // do something; 
      }; 

     }); 
})(); 

服務這裏有我的應用程序的一些背景。

第一屏 用戶輸入用戶名和密碼並將查詢發送到服務器。如果服務器返回true,用戶將通過$location.url('url');重定向到應用程序。

第二屏 控制器出現在屏幕上,呼叫ServiceService返回dataController正確填充。

到目前爲止,一切正常。

當我點擊我的註銷按鈕時,我摧毀了service中的data

當我用另一個用戶名和密碼重新登錄時,即使我在控制檯中看到服務器發送了正確的json,仍然會顯示前一位用戶的data。這就好像service.data第二次沒有更新。 .service是一個單身...它可能是deferred = $q.defer();需要重置?

請注意,如果我在第二個屏幕(登錄後)刷新瀏覽器,則會顯示正確的信息。

我很感激任何幫助。

回答

1

是否可以是deferred = $ q.defer();需要重置?

是的,你只是爲應用程序的生命創建一個實例,而不是每個API調用的實例。

事實上,使用$q作爲您的$http調用是完全不必要的,並且被認爲是螞蟻模式。


首先讓我們使用$q修復它,這樣它就可以工作。您需要創建每次使用一個新的承諾對象:

var deferred = $q.defer(); // your one time only object 

//makes the api call to get that data 
service.load = function() { 

應該是:

//makes the api call to get that data 
service.load = function() { 
    // new deferred object each use 
    var deferred = $q.defer(); 

然而$http本身返回承諾使你真正需要的是return $http不是創建一個新的承諾:

service.load = function() { 
    // return the $http promise 
    return $http({ 
     method: 'GET', 
     url: '/url', 
     headers: { 
      'Content-type': 'application/json' 
     }, 
     cache: false 
    }).then(function (response) { 
      service.data = response.data; 
      // instead of `deferred.resolve()` return the data 
      return service.data 
    }, function() { 
     // error handling code 
    }); 
}; 

對於你的loaded()方法,每次創建一個新的$q

+0

謝謝!謝謝!謝謝!我無法爲此感謝你! –

1

service.loaded是錯誤的邏輯, 如果加載創建數據延遲的決心,否則返回負載()本身:

service.loaded = function() {    
    if (service.data) { 
     var deferred = $q.defer(); 
     deferred.resolve(service.data); 
     return deferred.promise; 
    } else { 
     return service.load(); 
    } 
}; 

我會保持 '無功遞延= $ q.defer();'每個服務方法內部都有不同的實例,請勿在所有服務調用中共享。

+0

謝謝德米特里。你的答案是解決方案的一部分。 –