Кэшировать ответ службы HTTP 'Get' в AngularJS?

206

Я хочу иметь возможность создать пользовательский сервис AngularJS, который выбирает HTTP-запрос "Get", когда его объект данных пуст и заполняет объект данных в случае успеха.

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

Это возможно?

Теги:
caching
http-get

6 ответов

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

Angular $http имеет кеш построенный в. Согласно документам:

кеш - {boolean | Object} - логическое значение или объект, созданное с помощью $cacheFactory для включения или отключения кэширования ответа HTTP. Видеть $http Кэширование для более информация.

Логическое значение

Таким образом, вы можете установить cache в true в своих параметрах:

$http.get(url, { cache: true}).success(...);

или, если вы предпочитаете тип конфигурации конфигурации:

$http({ cache: true, url: url, method: 'GET'}).success(...);

Объект кэша

Вы также можете использовать кеш factory:

var cache = $cacheFactory('myCache');

$http.get(url, { cache: cache })

Вы можете реализовать его самостоятельно, используя $cacheFactory (особенно при использовании $resource):

var cache = $cacheFactory('myCache');

var data = cache.get(someKey);

if (!data) {
   $http.get(url).success(function(result) {
      data = result;
      cache.put(someKey, data);
   });
}
  • 1
    Можно ли реализовать кеш с помощью localStorage?
  • 1
    Если я проверю код angular: нет. Но должно быть довольно легко создать службу (localStorageService), которая хранит в localStorage - если доступно - и в $ cacheFactory - если нет.
Показать ещё 16 комментариев
46

Я думаю, что теперь еще проще. Это позволяет базовое кэширование для всех $http-запросов (которые наследует $resource):

 var app = angular.module('myApp',[])
      .config(['$httpProvider', function ($httpProvider) {
            // enable http caching
           $httpProvider.defaults.cache = true;
      }])
  • 45
    Вы вряд ли захотите кэшировать каждый http-запрос. Я не понимаю, когда это когда-нибудь случится?
  • 1
    Каждое приложение / модуль отличается, нет ?!
Показать ещё 1 комментарий
12

Более простой способ сделать это в текущей стабильной версии (1.0.6) требует гораздо меньше кода.

После настройки модуля добавьте factory:

var app = angular.module('myApp', []);
// Configure routes and controllers and views associated with them.
app.config(function ($routeProvider) {
    // route setups
});
app.factory('MyCache', function ($cacheFactory) {
    return $cacheFactory('myCache');
});

Теперь вы можете передать это в свой контроллер:

app.controller('MyController', function ($scope, $http, MyCache) {
    $http.get('fileInThisCase.json', { cache: MyCache }).success(function (data) {
        // stuff with results
    });
});

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

7

Посмотрите библиотеку angular-cache, если вам нравится встроенное кэширование в $http, но вам нужно больше контроля. Вы можете использовать его для беспрепятственного увеличения кеша $http с периодическими чистками времени и времени и возможностью сохранения кеша в localStorage, чтобы он был доступен для всех сеансов.

FWIW, он также предоставляет инструменты и шаблоны для того, чтобы сделать ваш кеш более динамичным типом хранилища данных, с которым вы можете взаимодействовать как POJO, а не только по умолчанию строки JSON. Не могу прокомментировать полезность этой опции.

(Затем, кроме того, связанная библиотека angular -data является своего рода заменой для $resource и/или Restangular, и зависит от angular -cache.)

  • 3
    Обратите внимание, что angular-data устарела. Последняя версия - js-data-angular js-data.io/v1.8.0/docs/js-data-angular
  • 0
    Библиотека angular-cache имеет функции, которые должны были быть встроены в $ cacheFactory Angular. Встроенное решение кажется почти бесполезным, учитывая его ограничения в возможности истечения срока действия определенных кэшей. Фабрика angular-cache также была одной из самых простых сторонних библиотек.
5

Поскольку фабрики AngularJS singletons, вы можете просто сохранить результат запроса http и получить его в следующий раз, когда ваша служба будет внедрена во что-то.

angular.module('myApp', ['ngResource']).factory('myService',
  function($resource) {
    var cache = false;
    return {
      query: function() {
        if(!cache) {
          cache = $resource('http://example.com/api').query();
        }
        return cache;
      }
    };
  }
);
  • 0
    У меня есть один вопрос, как проверить, не удалось ли GET, и в этом случае не помещать в кеш запрос $ resource ... ()
  • 0
    @robert, вы можете проверить второй аргумент метода .then или, что еще лучше, использовать обратный вызов .catch. Например, $ http .get (url) .then (successCallback, failCallback) или $ http .get (url) .then (successCallback, failCallback) .catch (errorCallback). Обратный вызов ошибки будет выполнен, даже если в failCallback произойдет что-то плохое. , хотя чаще избегать обратного вызова с ошибками и использовать .then (success) .catch (manageRequestFail). Надеюсь, что это поможет понять идею, больше информации в англоязычной документации.
2
angularBlogServices.factory('BlogPost', ['$resource',
    function($resource) {
        return $resource("./Post/:id", {}, {
            get:    {method: 'GET',    cache: true,  isArray: false},
            save:   {method: 'POST',   cache: false, isArray: false},
            update: {method: 'PUT',    cache: false, isArray: false},
            delete: {method: 'DELETE', cache: false, isArray: false}
        });
    }]);

установите для кеша значение true.

  • 0
    это безопасно?
  • 0
    Это было бы так же безопасно, как и клиентское приложение без самого браузера, как любое другое веб-приложение.

Ещё вопросы

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