So aktualisieren / ungültig machen Sie den $ resource-Cache in AngularJS

94

Ich habe eine einfache User $ -Ressource, die die Standardimplementierung des $ http-Cache wie folgt verwendet:

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

Dies funktioniert sehr gut, dh mein Server wird in meiner Anwendung nur einmal aufgerufen, dann wird der Wert aus dem Cache abgerufen.

Aber ich muss den Wert vom Server nach einer bestimmten Operation aktualisieren. Gibt es eine einfache Möglichkeit, das zu tun?

Vielen Dank.

Alexandre Bulté
quelle
1
Ich verwende instabil (1.1.5, aber ich denke, es ist seit 1.1.2 vorhanden) cache- {boolean|Cache}- Wenn true, wird ein Standard-$ http-Cache zum Zwischenspeichern der GET-Anforderung verwendet, andernfalls, wenn eine Cache-Instanz mit
Alexandre Bulté,
1
Ich habe ein ähnliches Problem, aber nur beim Testen. Wie kann ich dieses Ding auf Browserebene kaputt machen?
Chovy

Antworten:

116

Behalten Sie den Booleschen Wert und holen Sie sich den $httpCache:

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

Dann können Sie es wie jeden anderen Cache steuern, der mit $cacheFactoryeiner unten angegebenen Verwendungsinstanz erstellt wurde:

$httpDefaultCache.remove(key);
// Where key is the relative URL of your resource (eg: /api/user/current/51a9020d91799f1e9b8db12f)
Anthonny
quelle
52
Perfekt, danke! Genau das, wonach ich gesucht habe. Wenn Sie sich fragen, können Sie $ cacheFactory.get ('$ http'). Remove (Schlüssel) aufrufen, wobei der Schlüssel die relative URL Ihrer Ressource ist (z. B. / api / user / current / 51a9020d91799f1e9b8db12f).
Alexandre Bulté
2
Eigentlich stellte ich fest, dass ich beim Aufruf von remove () die vollständige URL zusammen mit allen Abfrageparametern angeben musste. Vermisse ich hier etwas?
shangxiao
3
Ich habe dynamische Abfrageparameter. Gibt es eine Möglichkeit, ab $resourceWerk auf die URL zuzugreifen ?
Suzanshakya
1
Während das funktioniert. Es kann komplexer sein als nötig. Eine bessere Lösung wäre, wenn dies implementiert würde: github.com/angular/angular.js/issues/9064
KFunk
5
Für mich hat $ cacheFactory.get ('$ http'). RemoveAll () den Trick gemacht, da ich alle zwischengespeicherten Daten löschen musste.
S. Baggy
18

Anstatt ein boolesches Argument in der cacheEigenschaft eines jeden zu verwenden action, können Sie eine mit $ cacheFactory erstellte Cache-Instanz weitergeben, über die Sie mehr Kontrolle haben können (dh den Cache löschen).

Anwendungsbeispiel:

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 }
    });
});
Variante
quelle
Vielen Dank. Ich habe das auch gesehen, aber ich habe nach einem "normalen" Weg gesucht, bevor ich diesen Weg
gegangen bin
1
scheint ein sehr "Standard" -Ansatz zu sein, der dem "Winkelweg" entspricht :)
Variante
1
Du hast recht. Ich meinte einen Ansatz mit dem Standard-Ressourcencache $.
Alexandre Bulté
6

Ich bin auf diesen Thread gestoßen, der nach etwas Ähnlichem gesucht hat, habe jedoch festgestellt, dass $ resource den Cache automatisch für Sie verwaltet, sodass das Löschen des Caches nicht erzwungen werden muss.

Die Idee ist, dass wenn Sie eine Ressource haben, die Sie abfragen können, diese Abfrageantwort zwischengespeichert wird. Wenn Sie jedoch etwas für dieselbe Ressource speichern, müssen die zuvor zwischengespeicherten Daten ungültig sein, damit sie für Sie gelöscht werden. Es macht Sinn, dass es so funktionieren würde.

Hier ist ein Code, den ich dazu verwende (Sie können den möglicherweise seltsam aussehenden Teil der Werkserstellung ignorieren und auf den "Klassen" -Körper achten).

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

Wenn Sie die Funktion listPlayers mehrmals aufrufen, wird beim ersten Aufruf eine http-Get-Anforderung gesendet, und alle nachfolgenden Aufrufe werden zwischengespeichert. Wenn Sie jedoch addPlayer aufrufen, wird ein http-Beitrag wie erwartet ausgeführt, und beim nächsten Aufruf von listPlayers wird ein http-Get ausgeführt (nicht zwischengespeichert).

Dies hält Sie davon ab, den Cache einer anderen Person ($ http) zu verwalten und zu versuchen, mit den URLs Schritt zu halten, die für Anforderungen verwendet werden und die Caches zum richtigen Zeitpunkt löschen.

Ich nehme an, die Moral der Geschichte hier ist, mit der Bibliothek zu arbeiten, und alles wird gut ... bis auf Fehler oder unvollständige Funktionen, aber Angular hat keine davon;)

ps Dies alles läuft unter AngularJS 1.2.0.

user605331
quelle
2
Ja, ich verstehe und erkenne an, dass die Angular-Ressource unter "normalen" Bedingungen weiß, wie und wann der Cache ungültig zu machen ist, und dass sie perfekt funktioniert. Mein Anwendungsfall war jedoch etwas anders: Ich wollte eine Aktualisierung erzwingen, da Angular nicht wissen konnte, dass eine Aktualisierung erforderlich war - das Benutzerobjekt wurde außerhalb der Angular-App geändert.
Alexandre Bulté
3
Kann jemand darauf hinweisen, wo dies dokumentiert ist? Ich habe dies bereits in Stack Overflow gelesen, kann es jedoch in der Dokumentation nicht erwähnen. Ich habe es auch in meiner App versucht, aber vielleicht habe ich auf dem Weg etwas falsch gemacht ...
Sunil D.
1
Es scheint jedoch nicht mit $ delete zu funktionieren. Der nächste Aufruf wird erneut aus dem Cache abgerufen und das gelöschte Element wird erneut angezeigt. Kann jemand bestätigen?
Lukus
: Dies wird zum Beispiel gehen hier nicht ngResource DO NOT HANDLE Cache - Annullierungs arbeiten stackoverflow.com/questions/25117388/...
HugoPoi