Как кэшировать ответ $ http для повторного использования в angularjs

0

Я пытаюсь использовать $ http.get() в качестве службы, предоставляющей контроллеры. Пожалуйста помоги!

erp.service('elementData',['$http', '$cacheFactory', function($http, $cacheFactory){
    var fetchCache = $cacheFactory('ele', {number: 1}); 

    $http({url: "./php/fetchElement.php", 
    method: 'GET'}).success(function(data){
        fetchCache.put(1, data.records);
        console.log(fetchCache.info('ele'));        
        //return fetchCache.get(1);
    });
    console.log(fetchCache.info('ele'));



}])

console.log(fetchCache.info( 'Ele')); обеспечить другой результат.

  • 0
    .success и .error запрещены. Используйте .then и .catch также как часть объекта параметров .get('/url/here', opts) вы можете .get('/url/here', opts) значение cache . Установите в true, и он будет иметь дело с кешем или предоставит ему объект cacheFactory . Он сделает всю работу за вас. Вот
Теги:

3 ответа

1

Чтобы эффективно кэшировать ответ от HTTP-вызова и возвращать, если он присутствует, я бы сделал что-то вроде этого

angular.module('app').factory('dataService', dataService);
dataService.$inject = ['$http', '$q'];

function dataService($http, $q) {
    var service = {
        getGroups: getGroups,
        _groupCache: null
    };

    return service;

    function getGroups() {
        // Return from local cache variable if we have it.
        if (service._groupCache) return $q.resolve(service._groupCache);
        // Otherwise, return from API.
        return $http.get("api/ms/groups/").then(
            function (response) {
                service._groupCache = response.data;
                return response.data;
            }
        );
    }

Затем его можно ввести в контроллер и использовать следующим образом:

angular.module('app').controller('PageCtrl', PageCtrl);

PageCtrl.$inject = ['dataService'];

function PageCtrl(dataService) {
    var vm = this;
    // "Public" properties
    vm.groups = null;
    dataService.getGroups().then(function (groups) {
        vm.groups = groups;
    });
}

Затем вы должны иметь доступ к группам внутри вашей страницы. При первом запуске этого кода _groupCache в сервисе будет пустым, поэтому он отправит HTTP-запрос. При последующих запусках будет заполнен _groupCache. Вы можете уточнить это, сохранив кешированные группы в локальном хранилище в браузере, который сохранит его в кэше даже после загрузки страницы.

Обратите внимание, что возврат функции getGroups ВСЕГДА будет асинхронным, поэтому все, что нуждается в этих данных, должно быть привязано к. Then по возврату getGroups, как в этом примере.

В вашем примере обратный вызов.success будет выполняться асинхронно, поэтому второй console.log будет выполняться до первого. Чтобы исправить эту проблему, вы должны переписать ее следующим образом:

erp.service('elementData',['$http', '$cacheFactory', function($http, $cacheFactory){
    var fetchCache = $cacheFactory('ele', {number: 1}); 

    $http({url: "./php/fetchElement.php", 
    method: 'GET'}).then(function(data){
        fetchCache.put(1, data.records);
        console.log(fetchCache.info('ele'));        
    }).then(function () {
        console.log(fetchCache.info('ele'));
    });
}])
  • 0
    @ user2671755 Что касается вашего вопроса в комментарии к другому ответу, нет проблем с кэшированием результата, как у вас, но вам нужно проверить кеш перед вызовом $ http get.
  • 0
    @ user2671755 Я обновил свой ответ, чтобы показать, как вы можете кэшировать данные в локальной переменной внутри фабрики / службы.
0

Спасибо за вашу помощь. Я также нашел это:

erp.run(['$http', '$rootScope',
    function($http, $rootScope) {      
     $http({ cache: true, url: './php/fetchElement.php', method: 'GET'})
        .success(function(data) {
          $rootScope.resource = data.records;         
        });
    }
]);

erp.service('elementData',['$rootScope',
   function($rootScope) {
        //console.log($rootScope.resource);
        if($rootScope.resource){
            return $rootScope.resource;
        }
    }
]);
0

вы можете использовать служебную переменную.

erp.service('elementData',['$http', '$cacheFactory', function($http, $cacheFactory){
    var resource = {};
    // var fetchCache = $cacheFactory('ele', {number: 1}); 
    resource.loadedData = null;
    resource.getData = function(callback){  
      $http({url: "./php/fetchElement.php", 
      method: 'GET'}).succes(function(data){
        callback(data);
      });        
          //return fetchCache.get(1);
    }
    console.log(fetchCache.info('ele'));

}]);


/*....
In side of your controller */ 
  if(elementData.loadedData){
    $scope.elementData = elementData.loadedData;
    process();
  } else {
    elementData.getData(function(data){
      $scope.elementData = data;
      elementData.loadedData = data;
      /*
        if you want set it on localStorage you can use as
        localStorage.loadedData instead of elementData.loadedData;
      */
      process();
    });
  }
  function process(){
    /* then you can use your data*/
  }
//....
  • 1
    Там, где у вас есть /* then you can use your data */ , что вводит в заблуждение, потому что в этот момент асинхронный обратный вызов getData все равно не вернется - проблема асинхронности просто перемещена в другое место в коде.
  • 1
    Есть ли способ кешировать извлеченные данные и повторно использовать. Правильно ли это, когда я утверждаю, что с вышеприведенным решением он выбирает сервер каждый раз, когда мы используем данные, и влияет на производительность (скорость)?
Показать ещё 1 комментарий

Ещё вопросы

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