Как обновить / сделать недействительным кеш $ resource в AngularJS

94

У меня есть простой ресурс User $, который использует реализацию кеша $ http по умолчанию, например:

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

Это работает очень хорошо, т.е. мой сервер вызывается в моем приложении только один раз, затем значение извлекается из кеша.

Но мне нужно обновить значение с сервера после определенной операции. Есть простой способ сделать это?

Спасибо.

Александр Булте
источник
1
Я использую нестабильную версию (1.1.5, но я думаю, что она существует с версии 1.1.2) cache- {boolean|Cache}- Если это правда, для кеширования запроса GET будет использоваться кеш $ http по умолчанию, в противном случае, если экземпляр кеша построен с
Александр Булте,
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).
Alexandre Bulté
2
На самом деле я обнаружил, что мне нужно указать полный URL-адрес вместе с любыми параметрами запроса при вызове remove (). Я что-то упустил?
шансяо
3
У меня есть параметры динамического запроса. Есть ли способ получить доступ к URL-адресу с $resourceзавода?
suzanshakya
1
Пока это работает. Это может быть больше сложности, чем нужно. Лучшим решением было бы, если бы это было реализовано: github.com/angular/angular.js/issues/9064
KFunk
5
Для меня $ cacheFactory.get ('$ http'). RemoveAll () помогло мне, так как мне нужно было очистить все кешированные данные.
С. Багги
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 }
    });
});
Вариант
источник
Спасибо. Я тоже это видел, но я искал "стандартный" способ сделать это, прежде чем идти по этому пути ...
Александр Булте
1
кажется очень "стандартным" подходом, соответствующим "угловому" :)
Вариант
1
Ты прав. Я имел в виду подход со стандартным кешем $ resource.
Alexandre Bulté
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-запрос на получение, а все последующие вызовы кэшируются. Если вы вызываете addPlayer, HTTP-сообщение выполняется, как ожидалось, а затем следующий вызов listPlayers выполнит HTTP-получение (не кешируется).

Это избавляет вас от необходимости управлять чужим ($ http) кешем и пытаться следить за тем, какие URL-адреса используются для запросов, а какие очищают кеши в нужное время.

Я полагаю, что мораль этой истории заключается в том, чтобы поработать с библиотекой, и все будет хорошо ... за исключением каких-либо ошибок или неполных функций, но в Angular их нет;)

ps Все это работает на AngularJS 1.2.0.

user605331
источник
2
Да, я понимаю и подтверждаю, что в «нормальных» условиях ресурс Angular знает, как и когда сделать кеш недействительным, и работает отлично. Но мой вариант использования был немного другим: я хотел принудительно обновить, потому что Angular не мог знать, что обновление было необходимо - объект пользователя был изменен вне приложения Angular.
Alexandre Bulté
3
Может ли кто-нибудь указать, где это задокументировано? Я читал об этом раньше в Stack Overflow, но не могу найти упоминания об этом в документации. Я тоже пробовал это в своем приложении, но, возможно, в процессе сделал что-то не так ...
Сунил Д.
1
Однако, похоже, он не работает с $ delete. При следующем вызове снова будет извлечен из кеша, и удаленный элемент снова появится. Кто-нибудь может подтвердить?
Лукус
Это не сработает. NgResource НЕ ОБРАБОТАТЬ аннулирование кеша, например, сюда: stackoverflow.com/questions/25117388/…
HugoPoi