Кеш HTTP-відповіді "Отримати" відповідь в AngularJS?


211

Я хочу мати змогу створити користувальницьку службу AngularJS, яка робить запит HTTP 'Get', коли об’єкт даних порожній і заповнює об'єкт даних успішно.

Наступного разу, коли буде здійснено дзвінок до цієї послуги, я хотів би обійти накладні витрати знову на запит HTTP і замість цього повернути кешований об’єкт даних.

Чи можливо це?

Відповіді:


315

$ Http у Angular має вбудований кеш-пам'ять . Згідно з документами:

кеш - {boolean | Object} - булеве значення або об'єкт, створений за допомогою $ cacheFactory для включення або відключення кешування HTTP-відповіді. Див. $ Http кешування для отримання додаткової інформації .

Булева величина

Таким чином, ви можете встановити cacheзначення true у його параметрах:

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

або, якщо ви віддаєте перевагу конфігураційному типу дзвінка:

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

Об'єкт кешу

Ви також можете використовувати кеш-завод:

var cache = $cacheFactory('myCache');

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

Ви можете реалізувати його самостійно за допомогою $ cacheFactory (особливо зручно при використанні $ ресурсу):

var cache = $cacheFactory('myCache');

var data = cache.get(someKey);

if (!data) {
   $http.get(url).success(function(result) {
      data = result;
      cache.put(someKey, data);
   });
}

47
Питання: у чому сенс збереження кешованих даних у $ cacheFactory .. чому б просто не зберегти їх у локальний об’єкт у Сервісі? Будь-які вагомі причини?
Спок

7
Заціни. Він надає вам безліч налаштувань, включаючи підтримку localStorage, підтримку таймауту, всілякі смаколики http://jmdobry.github.io/angular-cache/
Ерік Донохоу,

4
Мені особливо цікаво код стану 304 - чи працює кеш браузера без включення кешу: вірно? Якщо ні, чи кеш: true змушує його працювати? Кешування є постійним або він просто знаходиться в оперативній пам’яті і завантажується, коли сторінка закрита?
sasha.sochka

3
Будь-який спосіб вказати обмеження часу для цього кешу, не вручну застосовуючи його?
Марк

11
@Spock, $ cacheFactory - це послуга, яку можна використовувати в декількох контролерах та кутових компонентах. Його можна використовувати як загальну службу api, щоб кешувати всі ваші $ http в одній службі obj, а не мати різні об’єкти обслуговування для кожного з них.
Нірав Ганді

48

Я думаю, зараз є ще простіший шлях. Це дозволяє основне кешування для всіх $ http запитів (які успадковує $ ресурс):

 var app = angular.module('myApp',[])
      .config(['$httpProvider', function ($httpProvider) {
            // enable http caching
           $httpProvider.defaults.cache = true;
      }])

46
Ви навряд чи хочете кешувати кожен запит http. Я не бачу, коли це колись буде?
Спок

1
Кожна програма / модуль різна, ні ?!
rodrigo-silveira

13
Якщо ви хочете кешувати більшість запитів, то зручним є встановлення значень за замовчуванням.
Адріан Лінч

12

Простіший спосіб зробити це в поточній стабільній версії (1.0.6) вимагає набагато менше коду.

Після налаштування модуля додайте завод:

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

Ознайомтеся з кутовим кешем бібліотеки, якщо вам подобається вбудований кешування $ http, але хочете отримати більше контролю. Ви можете використовувати його для безперебійного збільшення кешу $ http за допомогою програми "Час життя", періодичних очищень та можливості збереження кешу в LocalStorage, щоб він був доступний протягом сеансів.

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

(Тоді, крім цього, пов’язані бібліотечні angular-data є своєрідною заміною ресурсу $ та / або Переустановки та залежать від кутового кешу.)


3
Зверніть увагу, що angular-dataзараз застаріле. Останнє js-data-angular оновлення
js-data.io/v1.8.0/docs/js-data-angular

Бібліотека кутових кешів має функції, які мали бути вбудовані у $ cacheFactory $ Angche. Вбудоване рішення здається майже марним, враховуючи обмеження в можливості закінчення терміну дії певних кеш-пам'яток. Фабрика кутових кешів також була однією з найпростіших бібліотек сторонніх виробників.
Дарріл

5

Оскільки заводи AngularJS є одинаковими , ви можете просто зберегти результат 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;
      }
    };
  }
);

У мене є одне питання, як перевірити, чи не вдалось отримати GET, і в такому випадку не вкласти в кеш ресурс $ ... query ()
robert

@robert Ви можете перевірити другий аргумент методу .then або ще краще використовувати зворотний виклик .catch. Наприклад, $ http .get (URL). , хоча частіше взагалі уникати зворотного зворотного дзвінка та використовувати .then (success) .catch (managementRequestFail). Сподіваємось, що допоможе зрозуміти ідею, більше інформації у кутовій документації $ http.
Фаїто

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}
        });
    }]);

встановити кеш істинним.


Це було б настільки ж безпечно, як клієнтська програма, що вилучає сам браузер, як і будь-який інший веб-додаток.
бхантол

-1

У куті 8 ми можемо зробити так:

import { Injectable } from '@angular/core';
import { YourModel} from '../models/<yourModel>.model';
import { UserService } from './user.service';
import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})

export class GlobalDataService {

  private me: <YourModel>;

  private meObservable: Observable<User>;

  constructor(private yourModalService: <yourModalService>, private http: HttpClient) {

  }

  ngOnInit() {

  }


  getYourModel(): Observable<YourModel> {

    if (this.me) {
      return of(this.me);
    } else if (this.meObservable) {
      return this.meObservable;
    }
    else {
      this.meObservable = this.yourModalService.getCall<yourModel>() // Your http call
      .pipe(
        map(data => {
          this.me = data;
          return data;
        })
      );
      return this.meObservable;
    }
  }
}

Ви можете назвати це так:

this.globalDataService.getYourModel().subscribe(yourModel => {


});

Вищевказаний код буде кешувати результат віддаленого API при першому виклику, щоб його можна було використовувати при подальших запитах до цього методу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.