AngularJSにHTTP 'Get'サービスの応答をキャッシュしますか?


211

データオブジェクトが空の場合にHTTP 'Get'リクエストを作成し、成功時にデータオブジェクトを生成するカスタムAngularJSサービスを作成できるようにしたいのですが。

次にこのサービスが呼び出されたときに、HTTPリクエストを再度行うオーバーヘッドをバイパスし、代わりにキャッシュされたデータオブジェクトを返します。

これは可能ですか?

回答:


315

Angularの$ httpにはキャッシュが組み込まれています。ドキュメントによると:

cache – {boolean | Object} – HTTP応答のキャッシュを有効または無効にするために$ cacheFactoryで作成されたブール値またはオブジェクト。詳細については、$ httpキャッシュを参照 してください

ブール値

だから、設定することができますcache、真のオプションで:

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

または、configタイプの呼び出しを希望する場合:

$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
これをチェックしてください。localStorageのサポート、タイムアウトのサポート、あらゆる種類の機能http://jmdobry.github.io/angular-cache/
Erik Donohoo

4
ステータスコード304に特に興味があります-ブラウザのキャッシュはcache:trueを有効にしなくても機能しますか?そうでない場合、cache:trueで機能しますか?キャッシュは永続的ですか、それともRAMだけにあり、ページが閉じられたときにアンロードされますか?
sasha.sochka 2015

3
手動で実装せずにこのキャッシュの時間制限を指定する方法はありますか?
Mark

11
@ Spock、$ cacheFactory自体は、複数のコントローラーおよび角度コンポーネント全体で使用できるサービスです。$ httpをすべて1つのサービスオブジェクトにキャッシュする汎用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 2014

13
リクエストの大部分をキャッシュしたい場合は、デフォルトをtrueに設定すると便利です。
エイドリアンリンチ

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

欠点の1つは、キー名も自動的に設定されるため、それらをクリアするのが難しいことです。うまくいけば、キー名を取得するために何らかの方法で追加されるでしょう。


7

$ httpのビルトインキャッシュが好きだが、より詳細な制御が必要な場合は、ライブラリangular-cacheをチェックしてください。これを使用して、存続時間、定期的なパージ、およびセッション全体で使用できるようにキャッシュをlocalStorageに永続化するオプションを使用して、$ httpキャッシュをシームレスに拡張できます。

FWIWは、デフォルトのJSON文字列だけでなく、POJOとして操作できるより動的な種類のデータストアにキャッシュを作成するためのツールとパターンも提供します。そのオプションのユーティリティについてはまだコメントできません。

(さらに、関連するライブラリangular-dataは、$ 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に組み込まれるべき機能が含まれています。組み込みのソリューションは、特定のキャッシュを期限切れにできるという制限があるため、ほとんど役に立たないようです。角度キャッシュファクトリは、実装が最も簡単なサードパーティライブラリの1つでもありました。
ダリル

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が失敗したかどうかをチェックするために一つの質問があり、その場合にはキャッシュに$リソース...クエリ()入れない
ロバート

@robertは、.thenメソッドの2番目の引数を確認できますが、.catchコールバックを使用することもできます。たとえば、$ http .get(url).then(successCallback、failCallback)または$ http .get(url).then(successCallback、failCallback).catch(errorCallback)failCallbackで何か問題が発生した場合でも、エラーコールバックが実行されます。 、ただし、failコールバックをまったく回避して.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に設定します。


これは、他のWebアプリと同様に、ブラウザ自体を備えたクライアントアプリケーションと同じくらい安全です。
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.