如何使用angularjs防止在同一页面中重复的http调用?

时间:2016-05-03 14:10:01

标签: angularjs

我有2个控制器,必须在视图中显示相同的数据(用户名)。

如何防止多次http通话?我的意思是, 如果已获得用户信息:将其保存到对象。 如果没有得到用户信息并且第二次呼叫到来:第二次呼叫必须等待第一次呼叫结束。

如果还有其他方法可以编写此代码,请告诉我。 我想在有和没有angularjs的缓存方法的情况下使用这个代码。如果你建议我使用缓存方法,请告诉我没有缓存方法的替代代码。

app.controller('myController1', function (getUserInfo) {
    getUserInfo.getList().then(function (userInfo) {
        vm.userInfo = userInfo;
    });
};

app.controller('myController2', function (getUserInfo) {
    getUserInfo.getList().then(function (userInfo) {
        vm.userInfo = userInfo;
    });
};               

app.factory('getUserInfo', function ($http) {
    return {
        getList: function () {
            return $http.post('http://www.foobar.com/api')
                .then(function (response) {
                    userInfo = response.data;
                    return data;
                }, function (error) {
                    return 'Some error happened';
                });
        }
    };

});

注意:Angularjs版本是:1.5.5和 用户刷新页面时必须刷新数据。因此我无法使用本地存储或会话。

4 个答案:

答案 0 :(得分:0)

两个控制器是否引用相同的vm.userInfo对象?如果是,您可以检查vm.userInfo是否已包含数据:

if(vm.userInfo.length < 1) {
    getUserInfo.getList().then(); //etc....
}

答案 1 :(得分:0)

对于只应在应用中加载一次的内容,您可以在.run部分加载它们,然后将加载的值设置为静态服务甚至localStorage / sessionStorage。

myApp.run(['getUserInfo', function(){
    getUserInfo.getList().then(function (userInfo) {
        sessionStorage.setItem('userInfo', JSON.stringify(userInfo));
    });
}]);

app.controller('myController1', function (getUserInfo) {
    vm.userInfo = sessionStorage.getItem('userInfo');
};

app.controller('myController2', function (getUserInfo) {
    vm.userInfo = sessionStorage.getItem('userInfo');
};

您的数据现在只加载一次,并且您已从应用中删除了不需要的HTTP调用。

答案 2 :(得分:0)

只需重写您的服务:

 return { 
    data:null,
    getList: function () {
        if(!data){
           var me = this;
           return $http.post('http://www.foobar.com/api')
            .then(function (response) {
                me.data = response.data;
                return data;
            }, function (error) {
                return 'Some error happened';
            });
    }else{
       var deferred = $q.defer();
       deferred.resolve(this.data);
       return deferred.promise;
    }
};

它只执行一次请求,如果你需要刷新它们,只需将数据设置为null,f5就会刷新数据。

答案 3 :(得分:0)

不确定为什么在同一页面中有两个控制器调用相同的功能。但无论如何,我试图使用$ rootScope为您的情况提供解决方案。希望它会帮助你:))

var app = angular.module('plunker', []).run(function($rootScope) {
        $rootScope.functionCalls = [];
    });

    

app.factory('getUserInfo', function ($http, $rootScope) {
    return {
        getList: function () {
          if ($rootScope.functionCalls['getList'] == 1) {
            return '';
          }
          else {
           $rootScope.functionCalls['getList'] = 1;
           return $http.post('https://api.github.com/users/mralexgray/repos')
                .then(function (response) {
                    userInfo = response.data;
                    return data;
                }, function (error) {
                    return 'Some error happened';
                });
          }
        }
    };

});

app.controller('myController1', function ($scope, getUserInfo) {
    var userInfo = getUserInfo.getList();
      if(userInfo != '')
        $scope.userInfo = userInfo;
});

app.controller('myController2', function ($scope, getUserInfo) {
    var userInfo = getUserInfo.getList();
      if(userInfo != '')
        $scope.userInfo = userInfo;
});