AngularJS에서 HTTP 'Get'서비스 응답을 캐시 하시겠습니까?


211

데이터 객체가 비어있을 때 HTTP 'Get'요청을하고 성공시 데이터 객체를 채우는 사용자 정의 AngularJS 서비스를 만들 수 있기를 원합니다.

다음에이 서비스를 호출 할 때 HTTP 요청을 다시하는 오버 헤드를 우회하고 대신 캐시 된 데이터 개체를 반환하고 싶습니다.

이게 가능해?

답변:


315

Angular의 $ http 에는 캐시가 내장되어 있습니다. 문서에 따르면 :

cache – {boolean | Object} – HTTP 응답의 캐싱을 활성화 또는 비활성화하기 위해 $ cacheFactory로 생성 된 부울 값 또는 객체 입니다. 자세한 내용은 $ http 캐싱을 참조하십시오 .

부울 값

그래서 당신은 설정할 수 있습니다 cache사실 의 옵션에서 :

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

또는 구성 유형의 통화를 선호하는 경우 :

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

캐시 객체

캐시 팩토리를 사용할 수도 있습니다.

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

47
질문 : 캐시 된 데이터를 $ cacheFactory에 저장하는 요점은 무엇입니까? 왜 서비스의 로컬 객체에 저장하지 않습니까? 좋은 이유가 있습니까?
Spock

7
이것 좀 봐. 그것은 당신이 로컬 스토리지 지원을 포함하여 사용자 화를 많이, 타임 아웃 지원, 케이크의 모든 종류의 제공 http://jmdobry.github.io/angular-cache/
에릭 Donohoo

4
상태 코드 304가 특히 궁금합니다. 캐시를 활성화하지 않고 브라우저 캐시가 작동합니까? 그렇지 않은 경우, cache : true가 작동합니까? 캐싱이 영구적입니까 아니면 RAM에 있고 페이지가 닫힐 때 언로드됩니까?
sasha.sochka

3
수동으로 구현하지 않고이 캐시에 시간 제한을 지정하는 방법이 있습니까?
Mark

11
@Spock, $ cacheFactory 자체는 여러 컨트롤러 및 각도 구성 요소에서 사용할 수있는 서비스입니다. 그것은 각각의 서비스 객체를 가지지 않고 모든 $ http를 단일 서비스 객체로 캐시하기 위해 일반 API 서비스로 사용될 수 있습니다.
Nirav Gandhi

48

지금은 더 쉬운 방법이 있다고 생각합니다. 이렇게하면 모든 $ http 요청 ($ resource가 상속 함)에 대한 기본 캐싱이 가능합니다.

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

46
모든 단일 HTTP 요청을 캐시하고 싶지는 않습니다. 언제 그런지 모르겠습니다.
Spock

1
모든 앱 / 모듈이 다릅니다.
rodrigo-silveira

13
대부분의 요청을 캐시하려면 기본값을 true로 설정하면 편리합니다.
Adrian Lynch

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의 내장 캐싱을 좋아하지만 더 많은 제어를 원하는 경우 라이브러리 angular-cache를 확인하십시오 . 이를 사용하면 수명이 다하고 주기적으로 삭제하고 캐시를 localStorage에 유지하는 옵션을 사용하여 $ http 캐시를 매끄럽게 확장하여 여러 세션에서 사용할 수 있습니다.

또한 캐시는 기본 JSON 문자열이 아닌 POJO와 상호 작용할 수있는보다 동적 인 종류의 데이터 저장소로 캐시를 만들기위한 도구와 패턴을 제공합니다. 해당 옵션의 유틸리티에 대해서는 아직 언급 할 수 없습니다.

그런 다음 관련 라이브러리 앵귤러 데이터 는 $ resource 및 / 또는 Restangular를 대체하는 것으로 angular-cache에 의존합니다.


3
참고 angular-data지금은 사용되지 않습니다를. 최신 버전은 js-data-angular js-data.io/v1.8.0/docs/js-data-angular
demisx

angular-cache 라이브러리에는 Angular의 $ cacheFactory에 내장되어 있어야하는 기능이 있습니다. 내장 솔루션은 특정 캐시를 만료시킬 수있는 한계가 있기 때문에 거의 쓸모가없는 것 같습니다. 앵귤러 캐시 팩토리는 구현하기 가장 쉬운 타사 라이브러리 중 하나였습니다.
Darryl

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이 실패했는지 확인하는 방법과 $ resource ... query () 캐시에 넣지 않는 방법에 대한 질문이 하나 있습니다.
robert

@robert 당신은 .then 메소드의 두 번째 인수를 확인하거나 더 나은 방법으로 .catch 콜백을 사용할 수 있습니다. 예를 들어 $ http .get (url) .then (successCallback, failCallback) 또는 $ http .get (url) .then (successCallback, failCallback) .catch (errorCallback) failCallback에서 문제가 발생하더라도 오류 콜백이 실행됩니다. 실패 콜백을 피하고 .then (success) .catch (manageRequestFail)를 사용하는 것이 일반적이지만 더 일반적입니다. 각도 $ http 문서의 아이디어, 더 많은 정보를 이해하는 데 도움이되기를 바랍니다.
Faito

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로 설정하십시오.


이것은 다른 웹 앱과 마찬가지로 브라우저 자체를 클라이언트 응용 프로그램에서 사용하는 것만 큼 안전합니다.
bhantol

-1

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의 결과를 캐시하여 해당 메소드에 대한 추가 요청에 사용할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.