データオブジェクトが空のときにHTTPの「取得」要求を行い、成功したときにデータオブジェクトを生成するカスタムAngularJSサービスを作成できるようにしたいです。
次回このサービスを呼び出すときには、HTTP要求を再度行うことによるオーバーヘッドを回避し、代わりにキャッシュされたデータオブジェクトを返します。
これは可能ですか?
Angularの $ http には キャッシュが組み込まれています があります。ドキュメントによると:
cache - {boolean | Object} - 作成されたブール値またはオブジェクト HTTP応答のキャッシュを有効または無効にする$ cacheFactoryを使用します。詳しくは $ 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 を使ってそれをあなた自身で実装することができます(特に$ 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
});
});
欠点の1つは、キー名も自動的に設定されるため、キーの削除が面倒になることです。うまくいけば、彼らはキー名を取得するために何らかの方法で追加するでしょう。
$ httpの組み込みキャッシングが好きだがもっと制御したいのであれば、ライブラリ angular-cache を調べてください。これを使用して、存続期間、定期的な消去、およびキャッシュをセッション間で使用できるようにlocalStorageに永続化するオプションを使用して、$ httpキャッシュをシームレスに増強できます。
また、デフォルトのJSON文字列ではなく、POJOとして対話できる、より動的な種類のデータストアにキャッシュを作成するためのツールとパターンも用意されています。そのオプションの有用性についてはまだコメントできません。
(そしてそれに加えて、関連ライブラリ 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に設定します。