2015-09-28 57 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

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