Come aggiornare / invalidare $ resource cache in AngularJS


94

Ho una semplice risorsa $ utente che utilizza l'implementazione della cache $ http predefinita in questo modo:

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

Funziona molto bene, cioè il mio server viene chiamato solo una volta nella mia applicazione, quindi il valore viene recuperato dalla cache.

Ma ho bisogno di aggiornare il valore dal server dopo una determinata operazione. C'è un modo semplice per farlo?

Grazie.


1
Sto usando unstable (1.1.5 ma penso che sia lì dalla 1.1.2) cache- {boolean|Cache}- Se true, verrà utilizzata una cache $ http predefinita per memorizzare nella cache la richiesta GET, altrimenti se un'istanza cache costruita con
Alexandre Bulté

1
Sto riscontrando un problema simile ma solo durante il test. come faccio a rompere questa cosa a livello di browser?
Chovy

Risposte:


116

Mantieni il valore booleano e ottieni la $httpcache:

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

Quindi puoi controllarlo come qualsiasi altra cache creata con $cacheFactoryun'istanza di utilizzo fornita di seguito:

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

52
Perfetto, grazie! Esattamente quello che stavo cercando. Per coloro che se lo chiedono, puoi chiamare $ cacheFactory.get ('$ http'). Remove (key), dove la chiave è l'URL relativo della tua risorsa (es: / api / user / current / 51a9020d91799f1e9b8db12f).
Alexandre Bulté

2
In realtà ho scoperto che avevo bisogno di specificare l'URL completo insieme a tutti i parametri di query quando chiamavo remove (). Mi manca qualcosa qui?
shangxiao

3
Ho parametri di query dinamici. C'è un modo per accedere all'URL dalla $resourcefabbrica?
suzanshakya

1
Mentre questo funziona. Potrebbe essere più complessità del necessario. Una soluzione migliore sarebbe se questo fosse implementato: github.com/angular/angular.js/issues/9064
KFunk

5
Per me, $ cacheFactory.get ('$ http'). RemoveAll () ha fatto il trucco, poiché avevo bisogno di cancellare tutti i dati memorizzati nella cache.
S. Baggy

18

Invece di usare un argomento booleano nella cacheproprietà di ciascuno action, puoi trasmettere un'istanza di cache creata con $ cacheFactory su cui puoi avere maggiore controllo (ad esempio, svuota la cache).

Utilizzo di esempio:

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

Grazie. Ho visto anche quello, ma stavo cercando un modo "standard" per farlo prima di intraprendere quel percorso ...
Alexandre Bulté

1
sembra un approccio molto "standard" conforme alla "via angolare" :)
Variante

1
Hai ragione. Intendevo un approccio con la cache $ risorsa standard.
Alexandre Bulté

6

Mi sono imbattuto in questo thread alla ricerca di qualcosa di simile, ma ho scoperto che $ resource gestirà automaticamente la cache, quindi non è necessario forzare la cancellazione della cache.

L'idea è che se hai una risorsa che puoi interrogare, quella risposta alla query verrà memorizzata nella cache, ma se salvi qualcosa per quella stessa risorsa, i dati precedentemente memorizzati nella cache devono essere non validi, quindi vengono cancellati per te. Ha senso che funzioni in questo modo.

Ecco un po 'di codice che uso per fare questo (puoi ignorare la parte di creazione di fabbrica forse dall'aspetto strano e prestare attenzione al corpo della "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;
    }]);

Se chiami più volte la funzione listPlayers, la prima chiamata effettua una richiesta http get e tutte le chiamate successive vengono memorizzate nella cache. Se chiami addPlayer, tuttavia, un post http viene eseguito come previsto, quindi la chiamata successiva a listPlayers eseguirà un recupero http (non memorizzato nella cache).

Ciò ti impedisce di gestire la cache di qualcun altro ($ http) e di cercare di tenere il passo con quali URL vengono utilizzati per le richieste e quali stanno svuotando le cache al momento giusto.

Suppongo che la morale della storia qui sia lavorare con la libreria e tutto andrà bene ... ad eccezione di eventuali bug o funzionalità incomplete, ma Angular non ne ha;)

ps Funziona tutto su AngularJS 1.2.0.


2
Sì, capisco e riconosco che in condizioni "normali" la risorsa Angular sa come e quando invalidare la cache, e funziona perfettamente. Ma il mio caso d'uso era leggermente diverso: volevo forzare un aggiornamento perché Angular non aveva modo di sapere che era necessario un aggiornamento: l'oggetto utente veniva modificato al di fuori dell'app Angular.
Alexandre Bulté

3
Qualcuno può indicare dove è documentato? L'ho letto prima su Stack Overflow, ma non riesco a trovare alcuna menzione nella documentazione. L'ho provato anche nella mia app, ma forse ho fatto qualcosa di sbagliato lungo la strada ...
Sunil D.

1
Tuttavia, non sembra funzionare con $ delete. La chiamata successiva verrà nuovamente estratta dalla cache e l'elemento eliminato riapparirà. Qualcuno può confermare?
Lukus

Questo non funzionerà ngResource non gestiscono invalidazione della cache andare qui per esempio: stackoverflow.com/questions/25117388/...
HugoPoi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.