несколько контроллеров angularjs одинаковые $ http кеш запроса

0

Работа над приложением, требующее отображения нескольких компонентов на той же странице, где нужны данные из одного и того же URL.

Например, у меня есть два компонента: один из них - это фактический контейнер данных, и оба они будут запрашивать статус компонента для отображения соответствующих данных.

завод данных

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 запроса на сервер.

Возможно ли (и если да, как это будет выглядеть), чтобы сделать перехватчик или службу, которая действует как фильтр для запросов и объединяет их в один запрос?

  • 0
    На мой взгляд, на этот вопрос нельзя ответить, если: (1) вы четко не объясните, зачем вам вообще нужны два запроса, и (2) кто является тем, кто получает запросы (имеется в виду то, что выполняется на стороне вашего сервера) ,
Теги:
angularjs-http

3 ответа

0
Лучший ответ

исправлено с использованием углового кэша HTTP, как указано в docs.angularjs.org/api/ng/service/$http.

У меня есть http-перехватчик, который я использую для ввода токена auth, и там я устанавливаю cache = true только для запросов GET.

Итак, теперь у моего перехватчика есть что-то вроде

function request(config) {

    ...

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

    ...
}

и это, кажется, делает трюк в самый раз.

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, статус фактически обновит обещание. До этого момента обещание останется нерешенным.

0

Blitz, почему ваш контроллер страницы не может вызвать этот два компонента и отправить данные вашим компонентам?

Я имею в виду, вам нужно иметь контроллер, который использует вашу фабрику данных. Затем вы передаете данные по области видимости вашему компоненту/директиве breadcrumb так же, как и ваша форма. Что-то вроде этого:

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>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню