服务返回异常数据

Service returning unexcepted data

本文关键字:数据 异常 返回 服务      更新时间:2023-09-26

我刚刚开始学习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');重定向到应用程序。

<<p> 第二屏幕/strong>控制器出现在屏幕上,调用ServiceService返回data, Controller正确填充

到目前为止一切正常。

当我点击登出按钮时,我破坏了service中的data

当我用另一个用户名和密码登录时,我仍然显示来自前一个用户的data,即使我在控制台上看到正确的json已由服务器发送。这就好像service.data不会在第二次更新一样。.service是一个单例…可能是deferred = $q.defer();需要重置吗?

请注意,如果我在第二个屏幕上刷新浏览器(在登录后),我将显示正确的信息。

谢谢你的帮助。

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

是的,你只在应用的生命周期中创建一个实例,而不是每个api调用一个实例。

事实上,对$http调用使用$q是完全没有必要的,它被认为是一种反模式。


首先让我们使用$q修复它,这样它就可以工作了。你需要为每次使用创建一个新的promise对象:

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

服务。装载的是错误的逻辑,如果已加载,则使用data创建延迟解析,否则返回load()本身:

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

我会在每个服务方法中保留'var deferred = $q.defer();'单独的实例,不要在所有服务调用中共享。