AngularJSで$リソースキャッシュを更新/無効化する方法


94

私は次のようにデフォルトの$ httpキャッシュ実装を使用する単純なUser $ resourceを持っています。

factory('User', function($resource){
    return $resource(endpoint + '/user/current/:projectId', {},
        {get: 
            {
                cache: true,
                method: 'GET'
            }
        }
    );
})

これは非常にうまく機能します。つまり、私のサーバーはアプリケーションで1回だけ呼び出され、次に値がキャッシュからフェッチされます。

しかし、特定の操作の後でサーバーから値を更新する必要があります。それを行う簡単な方法はありますか?

ありがとう。


1
不安定版を使用しています(1.1.5ですが、1.1.2以降にあると思います)cache{boolean|Cache}– trueの場合、デフォルトの$ httpキャッシュがGETリクエストのキャッシュに使用されます。それ以外の場合、キャッシュインスタンスが次のように構築されている場合
AlexandreBultéJun

1
私は同様の問題を抱えていますが、テスト時のみです。ブラウザーレベルでこれを無効にするにはどうすればよいですか?
chovy

回答:


116

ブール値を保持し、$httpキャッシュを取得します。

var $httpDefaultCache = $cacheFactory.get('$http');

次に$cacheFactory、で作成された別のキャッシュと同様に制御できます。

$httpDefaultCache.remove(key);
// Where key is the relative URL of your resource (eg: /api/user/current/51a9020d91799f1e9b8db12f)

52
パーフェクト、ありがとう!まさに私が探していたもの。これらの疑問については、$ cacheFactory.get( '$ http')。remove(key)を呼び出すことができます。keyはリソースの相対URLです(例:/ api / user / current / 51a9020d91799f1e9b8db12f)。
AlexandreBulté2013年

2
実際、remove()を呼び出すときに、クエリパラメータとともに完全なURLを指定する必要があることがわかりました。ここで何か不足していますか?
shangxiao

3
動的クエリパラメータがあります。$resource工場からURLにアクセスする方法はありますか?
スザンシャキャ

1
これは機能しますが。必要以上に複雑になる可能性があります。これが実装された場合のより良い解決策は次のとおり
KFunk

5
私にとっては、キャッシュされたデータをすべてクリアする必要があるため、$ cacheFactory.get( '$ http')。removeAll()がうまくいきました。
S.バギー

18

cacheそれぞれのプロパティでブール引数を使用する代わりにaction$ cacheFactoryで作成されたキャッシュインスタンスを渡すことができます。これにより、より詳細に制御できます(つまり、キャッシュをクリアできます)。

使用例:

app.factory('Todos', function($resource, $cacheFactory) {
    var cache = $cacheFactory('todo');
    return $resource(apiBaseUrl + '/todos/:id', { id: '@id' }, {
        'get': { method: 'GET', cache: cache  },
        'query': { method: 'GET', cache: cache, isArray: true }
    });
});

ありがとう。私もそれを見ましたが、その道を進む前にそれを行うための「標準的な」方法を探していました...
AlexandreBulté2013年

1
「角度のある方法」に準拠した非常に「標準的な」アプローチのようです:)
バリアント2013年

1
あなたが正しい。標準の$ resource cacheを使用するアプローチを意味しました。
AlexandreBulté2013年

6

似たようなものを探しているこのスレッドに出くわしましたが、$ resourceが自動的にキャッシュを管理するので、キャッシュを強制的にクリアする必要はありません。

クエリできるリソースがある場合、そのクエリ応答はキャッシュされますが、同じリソースに対して何かを保存する場合、以前にキャッシュされたデータは無効である必要があるため、データは消去されます。このように機能することは理にかなっています。

これを実行するために使用するコードをいくつか示します(奇妙に見える可能性のあるファクトリ作成部分を無視して、「クラス」本体に注意を払うことができます)。

'use strict';

sampleApp.players.$ng.factory('sampleApp.players.PlayerService', [
    '$log',
    '$resource',
    sampleApp.players.PlayerService = function ($log, $resource) {
        var service = {};

        $log.info('Creating player resource.');
        var Player = $resource('/api/players', {}, {query: {
            isArray: true,
            cache: true,
            method: 'GET'
        }});

        service.addPlayer = function(playerName) {
            $log.info('Saving a new player.');
            return new Player({name: playerName}).$save();
        };

        service.listPlayers = function () {
            $log.info('Fetching players.');
            return Player.query();
        };

        return service;
    }]);

listPlayers関数を数回呼び出すと、最初の呼び出しでhttp get要求が行われ、後続のすべての呼び出しがキャッシュされます。ただし、addPlayerを呼び出すと、期待どおりにhttp投稿が実行され、次にlistPlayersを呼び出すとhttp get(キャッシュされない)が実行されます。

これにより、他の誰かの($ http)キャッシュを管理し、どのURLが要求に使用され、どのURLが適切なタイミングでキャッシュをクリアしているのかを把握する必要がなくなります。

ここでの話の教訓はライブラリを操作することだと思いますが、バグや不完全な機能を除いてすべてがうまくいくでしょう...しかしAngularにはそれらがありません;)

psこれはすべてAngularJS 1.2.0で実行されています。


2
はい、私は理解し、「通常の」条件では、Angularリソースはキャッシュを無効化する方法とタイミングを知っており、完全に機能します。しかし、私のユースケースは少し異なりました。Angularは更新が必要であることを知る方法がなかったため、強制的に更新したかったのです。Angularアプリの外部でユーザーオブジェクトが変更されています。
AlexandreBulté2013

3
これが文書化されている場所を誰かが指摘できますか?これについてはStack Overflowで以前に読んだことがありますが、ドキュメントにそれについての言及はありません。私も自分のアプリで試しましたが、おそらく途中で何か間違ったことをしたかもしれません...
Sunil D.

1
ただし、$ deleteでは機能しないようです。次の呼び出しはキャッシュから再度プルし、削除されたアイテムが再び表示されます。誰か確認できますか?
2014

これは動作しませんngResource DO NOTハンドルキャッシュの無効化は、例えばここに行く:stackoverflow.com/questions/25117388/...
HugoPoi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.