angularjs多个控制器相同$ http请求缓存

时间:2016-08-04 11:53:20

标签: angularjs angularjs-http

处理一个应用程序,该应用程序需要在同一页面上显示需要来自同一个数据库的数据的多个组件。

根据示例,我有两个组件,一个是面包屑,一个是实际的数据容器,它们都会请求组件的状态以显示相关数据。

数据工厂

angular
    .module('app')
    .factory('data', function($http) { 
        this.getStatus = function() {
            return $http.get('/api/status/');
        }

        return this;
    });

控制器1

angular
    .module('app')
    .controller('breadcrumb', function(data, breadcrumbProcessor) {
         var _self = this;

         data
             .getStatus()
             .then(function(response) {
                 _self.activeBreadcrumb = breadcrumbProcessor(response.data); 
             });
    });

控制器2

angular
    .module('app')
    .controller('form', function(data, formProcessor) {
         var _self = this;

         data
             .getStatus()
             .then(function(response) {
                 _self.activeForm = formProcessor(response.data); 
             });
    });

第一个组件将是一个显示该过程阶段的面包屑,而第二个组件将是一个页面,您可以根据该阶段显示一个表单。因此,我将为两个组件调用相同的api“GET:/ api / stage /”,这将向服务器提出2个请求。

是否有可能(如果是这样的话)将拦截器或服务作为请求的过滤器并将它们合并为单个请求?

3 个答案:

答案 0 :(得分:0)

闪电战,您为什么页面控制器无法调用这两个组件并将数据发送到您的组件?

我的意思是,你需要一个使用你的数据工厂的控制器。然后,按范围将数据传递给面包屑组件/指令,与表单相同。像这样:



angular.module('myApp')
  .controller('ParentController', function (data, $scope) {
    data.getStatus()
             .then(function(response) {
                 $scope.yourData = response.data; 
             });
  })
  .directive('breadcrumb',   function () {
    return {
      restrict: 'A',
      replace: true,
      transclude: false,
      scope: {
        yourData: '='
      },
      templateUrl: 'directives/breadcrumb.html',
      link: function(scope){
        scope.$watch('yourData', function (newValue) {
          scope.activeBreadcrumb = breadcrumbProcessor(newValue);
        });
      }
    };
  })
  .directive('yourForm',   function () {
    return {
      restrict: 'A',
      replace: true,
      transclude: false,
      scope: {
        yourData: '='
      },
      templateUrl: 'directives/your-form.html',
      link: function(scope){      
        scope.$watch('yourData', function (newValue) {
          scope.activeForm = formProcessor(newValue);
        });
      }
    };
  });

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="ParentController">
  <breadcrumb your-data="yourData" />
  <your-form your-data="yourData" />  
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您也可以使用不同的工厂来获取存储的数据(如果可用):

angular
  .module('app')
  .factory('data', function($http) {
    var vm = this;

    // save to inner variables. those are not
    // accessible from outside the factory
    var statusPromise = $q.defer();

    vm.status = deferred.promise;

    // now, the data is fetched when this factory is
    // initialized (included somewhere)
    $http.get('/api/status/').then(function(res) {
      statusPromise.resolve(res.data);
    });

    return vm;
});

这样,您在申请状态时总能得到承诺。 如果$ http已经完成,则会返回已解决的承诺。 如果没有,这仍然会返回承诺(稍后会解决)。

这意味着一旦初始化此工厂,就会获取数据。如果您不想要这种行为,可以使用以下语法创建getStatus函数:

this.getStatus = function() {
  if (!vm.promiseResolvedAlready) {
    $http.get('/api/status/').then(function(res) {
      statusPromise.resolve(res.data);
      vm.promiseResolvedAlready = true;
    });
  }

  return vm.status;
}

并删除内联$http请求。这样,当有人第一次调用getStatus时,状态实际上会更新承诺。直到那时,承诺仍然没有得到解决。

答案 2 :(得分:0)

使用docs.angularjs.org/api/ng/service/$http中所述的角度http缓存修复它。

我有一个用于注入auth令牌的http拦截器,我只为GET请求设置了cache = true。

所以现在,我的拦截器有类似

的东西
function request(config) {

    ...

    if(config.method == "GET") {
        config.cache = true;
    }

    ...
}

这似乎恰到好处。