Как кэшировать http get сервис в angularjs
Я хочу иметь возможность создать пользовательский сервис, который получает запрос http get в случае, если объект данных ts пуст и заполняет объект данных в случае успеха. При следующем вызове службы устройство не будет вызывать http get, а вместо этого представит объект данных.
Есть идеи как это сделать?
6 ответов
$ Http Angular имеет встроенный кеш. Согласно документам:
cache - {boolean|Object} - логическое значение или объект, созданный с помощью $cacheFactory для включения или отключения кэширования ответа HTTP. Смотрите $http Caching для получения дополнительной информации.
Логическое значение
Таким образом, вы можете установить cache
чтобы истина в его вариантах:
$http.get(url, { cache: true}).success(...);
или, если вы предпочитаете тип конфигурации вызова:
$http({ cache: true, url: url, method: 'GET'}).success(...);
Cache Object
Вы также можете использовать фабрику кеша:
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);
});
}
Я думаю, что теперь есть еще более легкий путь. Это включает базовое кэширование для всех запросов $http (которые наследует $resource):
var app = angular.module('myApp',[])
.config(['$httpProvider', function ($httpProvider) {
// enable http caching
$httpProvider.defaults.cache = true;
}])
Более простой способ сделать это в текущей стабильной версии (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
});
});
Недостатком является то, что имена ключей также настраиваются автоматически, что может затруднить их очистку. Надеюсь, они каким-то образом добавят имена ключей.
Посмотрите библиотеку angular-cache, если вам нравится встроенное кэширование $http, но вы хотите больше контроля. Вы можете использовать его для плавного увеличения кеша $http с помощью периодических очисток по времени жизни и возможностью сохранения кеша в localStorage, чтобы он был доступен между сеансами.
Кроме того, он также предоставляет инструменты и шаблоны для превращения вашего кэша в более динамичное хранилище данных, с которым вы можете взаимодействовать как POJO, а не просто строки JSON по умолчанию. Пока не можете комментировать полезность этой опции.
(Кроме того, связанная библиотека angular-data является своего рода заменой $resource и / или Restangular и зависит от angular-cache.)
Поскольку фабрики 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;
}
};
}
);
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
В Angular 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 при первом вызове, чтобы его можно было использовать в дальнейших запросах к этому методу.