Як оновити / анулювати кеш $ ресурсу в 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}- Якщо значення true, кеш-пам'ять $ http буде використана для кешування запиту GET, інакше якщо екземпляр кешу, побудований за допомогою
Alexandre Bulté

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), при цьому ключ - це відносна URL-адреса вашого ресурсу (наприклад: / api / user / current / 51a9020d91799f1e9b8db12f).
Alexandre Bulté

2
Насправді я виявив, що мені потрібно вказати повну URL-адресу разом з будь-якими параметрами запиту під час виклику remove (). Мені чогось тут не вистачає?
shangxiao

3
У мене є динамічні параметри запиту. Чи є спосіб отримати доступ до URL-адреси із $resourceзаводу?
suzanshakya

1
Поки це працює. Це може бути більш складним, ніж потрібно. Кращим рішенням було б, якби це було впроваджено: github.com/angular/angular.js/issues/9064
KFunk

5
Для мене $ cacheFactory.get ('$ http'). RemoveAll () зробив трюк, оскільки мені потрібно було очистити всі кешовані дані.
S. Baggy

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
Ти маєш рацію. Я мав на увазі підхід зі стандартним кешем $ ресурсів.
Alexandre Bulté

6

Я натрапив на цей потік, шукаючи щось подібне, але виявив, що ресурс $ буде автоматично керувати кешем для вас, тому немає необхідності примусово очищати кеш.

Ідея полягає в тому, що якщо у вас є ресурс, який ви можете запитувати, відповідь на запит буде кешована, але якщо ви збережете щось для цього самого ресурсу, раніше кешовані дані повинні бути недійсними, тому вони будуть очищені для вас. Має сенс, що це спрацювало б так.

Ось деякий код, який я використовую для цього (ви можете проігнорувати можливу дивовижну частину створення фабрики та звернути увагу на тіло "класу").

'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.


2
Так, я розумію і визнаю, що в "звичайних" умовах ресурс Angular знає, як і коли зробити недійсною кеш-пам'ять, і це чудово працює. Але мій варіант використання був дещо іншим: я хотів змусити оновити, оскільки Angular не міг знати, що потрібно оновлення - користувальницький об'єкт модифікується за межами програми Angular.
Alexandre Bulté

3
Хтось може вказати, де це задокументовано? Я вже читав про це в Stack Overflow, але не можу знайти жодної згадки про це в документації. Я теж спробував це в своєму додатку, але, можливо, вчинив щось не так по дорозі ...
Суніл Д.

1
Однак, схоже, це не працює з $ delete. Наступний виклик знову витягнеться з кешу, а видалений елемент знову з’явиться. Хтось може підтвердити?
Лукус,

Це не буде працювати ngResource НЕ чіпайте кеш недійсності йди сюди, наприклад: stackoverflow.com/questions/25117388 / ...
HugoPoi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.