Comment actualiser / invalider le cache de ressources $ dans AngularJS

94

J'ai une simple ressource User $ qui utilise l'implémentation par défaut du cache $ http comme ceci:

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

Cela fonctionne très bien, c'est-à-dire que mon serveur n'est appelé qu'une seule fois dans mon application, puis la valeur est extraite du cache.

Mais j'ai besoin de rafraîchir la valeur du serveur après une certaine opération. Y a-t-il un moyen simple de le faire?

Merci.

Alexandre Bulté
la source
1
J'utilise unstable (1.1.5 mais je pense que c'est là depuis 1.1.2) cache- {boolean|Cache}- Si vrai, un cache $ http par défaut sera utilisé pour mettre en cache la requête GET, sinon si une instance de cache construite avec
Alexandre Bulté
1
J'ai un problème similaire mais uniquement lors des tests. comment puis-je supprimer cette chose au niveau du navigateur?
chovy

Réponses:

116

Gardez le booléen et récupérez le $httpcache:

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

Ensuite, vous pouvez le contrôler comme n'importe quel autre cache créé avec $cacheFactory, une instance d'utilisation fournie ci-dessous:

$httpDefaultCache.remove(key);
// Where key is the relative URL of your resource (eg: /api/user/current/51a9020d91799f1e9b8db12f)
Anthonny
la source
52
Parfait, merci! Exactement ce que je cherchais. Pour ceux qui se demandent, vous pouvez appeler $ cacheFactory.get ('$ http'). Remove (key), avec key étant l'URL relative de votre ressource (ex: / api / user / current / 51a9020d91799f1e9b8db12f).
Alexandre Bulté
2
En fait, j'ai trouvé que je devais spécifier l'URL complète avec tous les paramètres de requête lors de l'appel de remove (). Est-ce que j'ai râté quelque chose?
shangxiao
3
J'ai des paramètres de requête dynamiques. Existe-t-il un moyen d'accéder à l'url depuis l' $resourceusine?
suzanshakya
1
Pendant que cela fonctionne. Cela peut être plus complexe que nécessaire. Une meilleure solution serait si cela était implémenté: github.com/angular/angular.js/issues/9064
KFunk
5
Pour moi, $ cacheFactory.get ('$ http'). RemoveAll () a fait l'affaire, car j'avais besoin d'effacer toutes les données mises en cache.
S.Baggy
18

Au lieu d'utiliser un argument booléen dans la cachepropriété de chacun, actionvous pouvez transmettre une instance de cache créée avec $ cacheFactory sur laquelle vous pouvez avoir plus de contrôle (c'est-à-dire effacer le cache).

Exemple d'utilisation:

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 }
    });
});
Une variante
la source
Merci. J'ai vu ça aussi, mais je cherchais une façon "standard" de le faire avant de s'engager dans cette voie ...
Alexandre Bulté
1
semble être une approche très "standard" conforme à la "voie angulaire" :)
Variante
1
Vous avez raison. Je voulais dire une approche avec le cache de ressources standard $.
Alexandre Bulté
6

Je suis tombé sur ce fil à la recherche de quelque chose de similaire, mais j'ai trouvé que $ resource gérera automatiquement le cache pour vous, il n'est donc pas nécessaire de forcer l'effacement du cache.

L'idée est que si vous avez une ressource que vous pouvez interroger, cette réponse de requête sera mise en cache, mais si vous enregistrez quelque chose pour cette même ressource, les données précédemment mises en cache doivent être invalides, elles sont donc effacées pour vous. Il est logique que cela fonctionne de cette façon.

Voici un peu de code que j'utilise pour faire cela (vous pouvez ignorer la partie de création d'usine peut-être étrange et faire attention au corps "classe").

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

Si vous appelez la fonction listPlayers plusieurs fois, le premier appel effectue une requête http get et tous les appels suivants sont mis en cache. Si vous appelez addPlayer cependant, une publication http est effectuée comme prévu, puis le prochain appel à listPlayers effectuera un get http (non mis en cache).

Cela vous empêche de gérer le cache de quelqu'un d'autre ($ http) et d'essayer de savoir quelles URL sont utilisées pour les requêtes et lesquelles effacent les caches au bon moment.

Je suppose que la morale de l'histoire ici est de travailler avec la bibliothèque et tout ira bien ... sauf pour les bogues ou les fonctionnalités incomplètes, mais Angular n'en a aucun;)

ps Tout cela fonctionne sur AngularJS 1.2.0.

user605331
la source
2
Oui, je comprends et reconnais que dans des conditions «normales», la ressource Angular sait comment et quand invalider le cache, et cela fonctionne parfaitement. Mais mon cas d'utilisation était légèrement différent: je voulais forcer une actualisation car Angular n'avait aucun moyen de savoir qu'une actualisation était nécessaire - l'objet utilisateur étant modifié en dehors de l'application Angular.
Alexandre Bulté
3
Quelqu'un peut-il indiquer où cela est documenté? J'ai déjà lu à ce sujet sur Stack Overflow, mais je ne trouve aucune mention à ce sujet dans la documentation. Je l'ai essayé aussi dans mon application, mais j'ai peut-être fait quelque chose de mal en cours de route ...
Sunil D.
1
Il ne semble cependant pas fonctionner avec $ delete. Le prochain appel sera à nouveau extrait du cache et l'élément supprimé réapparaîtra. Quelqu'un peut-il confirmer?
Lukus
Cela ne fonctionnera pas ngResource NE PAS MANIPULER infirmation allez ici par exemple de cache: stackoverflow.com/questions/25117388/...
HugoPoi