【问题标题】:How to refresh / invalidate $resource cache in AngularJS如何在 AngularJS 中刷新/使 $resource 缓存无效
【发布时间】:2013-06-08 05:10:10
【问题描述】:

我有一个简单的用户 $resource,它使用默认的 $http 缓存实现,如下所示:

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

这很好用,即我的服务器只在我的应用程序中调用一次,然后从缓存中获取值。

但是我需要在某个操作后从服务器刷新值。有没有简单的方法可以做到这一点?

谢谢。

【问题讨论】:

  • 我使用的是不稳定的(1.1.5,但我认为它是从 1.1.2 开始的)cache{boolean|Cache} – 如果为 true,则默认为 $http 缓存将用于缓存 GET 请求,否则如果使用构建的缓存实例
  • 我遇到了类似的问题,但仅在测试时。我如何在浏览器级别破坏这个东西?

标签: angularjs angularjs-resource


【解决方案1】:

保留布尔值并获取$http 缓存:

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

然后您可以像使用$cacheFactory 制作的任何其他缓存一样控制它,下面提供了一个使用实例:

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

【讨论】:

  • 完美,谢谢!正是我想要的。对于那些想知道的人,您可以调用 $cacheFactory.get('$http').remove(key),其中 key 是资源的相对 URL(例如:/api/user/current/51a9020d91799f1e9b8db12f)。
  • 其实我发现调用remove()的时候需要指定完整的url和查询参数。我在这里错过了什么吗?
  • 我有动态查询参数。有没有办法从$resource factory 访问网址?
  • 这行得通。它可能比需要的更复杂。更好的解决方案是:github.com/angular/angular.js/issues/9064
  • 对我来说,$cacheFactory.get('$http').removeAll() 成功了,因为我需要清除所有缓存的数据。
【解决方案2】:

您可以传递使用$cacheFactory 创建的缓存实例,而不是在每个cache 属性中使用布尔参数,您可以对其进行更多控制(即清除缓存)。

示例用法:

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

【讨论】:

  • 谢谢。我也看到了,但在走这条路之前,我一直在寻找一种“标准”的方式来做到这一点......
  • 似乎是一种非常“标准”的方法,符合“角度方式”:)
  • 你是对的。我的意思是使用标准 $resource 缓存的方法。
【解决方案3】:

我偶然发现这个线程正在寻找类似的东西,但发现 $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 get 请求,所有后续调用都会被缓存。但是,如果您调用 addPlayer,则会按预期执行 http post,然后对 listPlayers 的下一次调用将执行 http get(未缓存)。

这使您无需管理其他人的 ($http) 缓存并尝试了解哪些 url 用于请求以及哪些在正确的时间清除缓存。

我想这里的故事的寓意是使用库,一切都会好起来的......除了任何错误或不完整的功能,但 Angular 没有任何这些;)

附言这一切都在 AngularJS 1.2.0 上运行。

【讨论】:

  • 是的,我理解并承认,在“正常”条件下,Angular 资源知道如何以及何时使缓存无效,并且可以完美运行。但我的用例略有不同:我想强制刷新,因为 Angular 无法知道需要刷新 - 用户对象在 Angular 应用程序之外被修改。
  • 谁能指出这是记录在哪里?我之前在 Stack Overflow 上读过这方面的内容,但在文档中找不到任何提及。我在我的应用程序中也尝试过,但可能在此过程中做错了什么......
  • 它似乎不适用于 $delete。下一次调用将再次从缓存中提取,删除的项目将重新出现。谁能确认一下?
  • 这不起作用 ngResource DO NOT HANDLE 缓存失效 例如:stackoverflow.com/questions/25117388/…
猜你喜欢
  • 2016-08-31
  • 2014-09-26
  • 1970-01-01
  • 1970-01-01
  • 2020-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-07
相关资源
最近更新 更多