Javascript angularjs:如何向资源对象添加缓存?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12225475/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
angularjs: how to add caching to resource object?
提问by iamgopal
To add caching inside http is pretty straight forward. ( by passing cache=true )
在 http 中添加缓存非常简单。(通过传递 cache=true )
http://docs.angularjs.org/api/ng.$httphas Cache option.
http://docs.angularjs.org/api/ng.$http有缓存选项。
How do I add similar functionality in $resource in angularjs ?
如何在 angularjs 的 $resource 中添加类似的功能?
回答by Narretz
回答by asgoth
Implementing your own cache in AngularJs is quite easy. Just use $cacheFactory:
在 AngularJs 中实现你自己的缓存非常容易。只需使用$cacheFactory:
app.factory('myService', function($resource, $cacheFactory) {
var cache = $cacheFactory('myService');
var User = $resource('/user/:userId', {userId:'@id'});
return {
getResource: function(userId) {
var user = cache.get(userId);
if (!user) {
user = User.get({userId:userId});
cache.put(userId, user);
}
return user;
}
};
});
回答by Bramus
As the docs state, $resourcehas built-in support for $cacheFactory. You can pass it in via the cache
property of each action:
正如文档所述,$resource内置了对$cacheFactory 的支持。您可以通过cache
每个操作的属性传入它:
cache
–{boolean|Cache}
– Iftrue
, a default$http
cache will be used to cache theGET
request, otherwise if a cache instance built with$cacheFactory
, this cache will be used for caching.
cache
–{boolean|Cache}
– 如果true
,$http
将使用默认缓存来缓存GET
请求,否则如果使用 构建的缓存实例$cacheFactory
,将使用该缓存进行缓存。
Example usage:
用法示例:
app.factory('Todos', function($resource, $cacheFactory) {
var todosCache = $cacheFactory('Todos');
return $resource(apiBaseUrl + '/todos/:id', {id: '@id'}, {
'get': { method:'GET', cache: todosCache},
'query': { method:'GET', cache: todosCache, isArray:true }
});
});
回答by Jean F.
You can also set default cache for $http and thus for $resource which is based on it.
您还可以为 $http 以及基于它的 $resource 设置默认缓存。
My settings with the excellent angular-cacheallowing LocalStorage and compliant with $cacheFactory:
我的设置具有出色的角度缓存,允许 LocalStorage 并符合 $cacheFactory:
app.run(function($http, DSCacheFactory) {
DSCacheFactory('defaultCache', {
deleteOnExpire: 'aggressive',
storageMode: 'localStorage'
});
$http.defaults.cache = DSCacheFactory.get('defaultCache');
});
回答by Iainzor
This doesn't seem to be mentioned here but you can also overwrite the default methods.
这里似乎没有提到这一点,但您也可以覆盖默认方法。
app.factory("List", ["$resource", function($resource) {
return $resource("./lists/:path/:action.json", {}, {
get: {
method: "GET",
cache: true
}
});
}]);
回答by bfricka
Looking at the angular-resource source indicates that triggering caching isn't possible with the way it is currently written.
查看 angular-resource 源表明当前编写的方式无法触发缓存。
Here's the request object from the source:
这是来自源的请求对象:
$http({
method: action.method,
url: route.url(extend({}, extractParams(data), action.params || {}, params)),
data: data
}).then(...)
There are a few potential ways to deal with this.
有几种可能的方法来处理这个问题。
First, you could cache locally using client-side persistence. I use amplify.storewith wrapper (b/c I don't really like the API syntax). There are a variety other storage solutions depending on what you're looking for and what browser's your targeting. Quite a few people use lawnchairas well.
首先,您可以使用客户端持久性在本地缓存。我将amplify.store与包装器一起使用(b/c 我不太喜欢 API 语法)。根据您要查找的内容以及您的目标浏览器,还有多种其他存储解决方案。相当多的人也使用草坪椅。
You can then stringify and store your models locally and update them based on whatever rules or time limits you desire.
然后,您可以在本地对模型进行字符串化和存储,并根据您想要的任何规则或时间限制更新它们。
Another solution is to simply modify angular resource to accept the parameters you're looking for. This could be as simple (simply add an additional argument to $resource) or complex as you need it to be.
另一种解决方案是简单地修改 angular 资源以接受您正在寻找的参数。这可以像您需要的那样简单(只需向 $resource 添加一个额外的参数)或复杂。
e.g.
例如
function ResourceFactory(url, paramDefaults, actions, cache) {
...
var cache = cache != null ? cache : false; // Set default to false
$http({
method: action.method,
url: route.url(extend({}, extractParams(data), action.params || {}, params)),
data: data,
cache: cache
}).then(...)
}
Finally, depending on you requirements, it might be significantly easier to simply create your own resource, using angular.factory to create a service. One of the advantages of ngResource is that is does all of the string interpolation work for you when translating parameters. However, you can certainly barrow this logic for parsing if you need it, or write your own based on the models you're using.
最后,根据您的要求,使用 angular.factory 创建服务,简单地创建自己的资源可能会容易得多。ngResource 的优点之一是在转换参数时为您完成所有字符串插值工作。但是,如果需要,您当然可以使用此逻辑进行解析,或者根据您使用的模型编写自己的逻辑。
回答by Ashish
I just came across this really well thought out module called angular-cached-resource that will do the job for you. https://github.com/goodeggs/angular-cached-resource
我刚刚遇到了这个经过深思熟虑的名为 angular-cached-resource 的模块,它将为您完成这项工作。https://github.com/goodeggs/angular-cached-resource
It is a drop in replacement for $resource, with added functionality of cache management using localStorage. If your browser doesnt support local storage, you will not get any caching benefit. Here's an example of how you can use it:
它是 $resource 的替代品,增加了使用 localStorage 的缓存管理功能。如果您的浏览器不支持本地存储,您将无法获得任何缓存优势。这是一个如何使用它的示例:
The old way using $resource:
使用 $resource 的旧方法:
var Entry = $resource('/entries/:slug', {slug: '@slug'});
var announcement = new Entry();
announcement.slug = 'announcing-angular-cached-resource';
announcement.title = 'Announcing Angular Cached Resource';
announcement.body = 'Here is why Angular Cached Resource is awesome!';
announcement.$save(function() {
alert('Saved announcement.');
});
The new way using $cachedResource:
使用 $cachedResource 的新方法:
var Entry = $cachedResource('entries', '/entries/:slug', {slug: '@slug'});
var announcement = new Entry();
announcement.slug = 'announcing-angular-cached-resource';
announcement.title = 'Announcing Angular Cached Resource';
announcement.body = 'Here is why Angular Cached Resource is awesome!';
announcement.$save(function() {
alert('Saved announcement.');
});
The only differences in the code are:
代码中的唯一区别是:
- Use $cachedResource instead of $resource
- Provide a "key" (
entries
in the example above) so that you can refer to it even between page refreshes or reloads. These entries persist since out of the box it uses localStorage.
- 使用 $cachedResource 而不是 $resource
- 提供一个“键”(
entries
在上面的示例中),以便您甚至可以在页面刷新或重新加载之间引用它。这些条目保持不变,因为它使用 localStorage 开箱即用。
A detailed tutorial is available here: https://github.com/goodeggs/bites/blob/master/src/documents/open_source/2014-04-24-angular-cached-resource.md
此处提供详细教程:https: //github.com/goodeggs/bites/blob/master/src/documents/open_source/2014-04-24-angular-cached-resource.md
Also note Angular 2.0 may support something like this out of the box: https://docs.google.com/document/d/1DMacL7iwjSMPP0ytZfugpU4v0PWUK0BT6lhyaVEmlBQ/edit
另请注意,Angular 2.0 可能开箱即用地支持这样的内容:https: //docs.google.com/document/d/1DMacL7iwjSMPP0ytZfugpU4v0PWUK0BT6lhyaVEmlBQ/edit
回答by Culpepper
I'm using angular-resource 1.5.5 and set my code up the following way:
我正在使用 angular-resource 1.5.5 并按以下方式设置我的代码:
Summary
概括
Set actionas query, and since the "query" action is expecting a response deserialized as an array, isArray will need to be explicitly set to true. My understanding is by default ngResource actions expect objects except query. See here
将action设置为query,并且由于“查询”操作期望将响应反序列化为数组,因此需要将 isArray 显式设置为 true。我的理解是默认情况下 ngResource 操作期望对象除外查询。 看这里
Controller
控制器
angular.module("app")
.controller('myCtrl',['$scope','myService',function($scope, myService) {
$scope.myData= myService.myResource.query();
}]);
Service
服务
angular.module('app')
.factory('myService',['$resource',function($resource){
var baseUrl = 'http://www.MyExample.com/';
return{
myResource:$resource(baseURL + '/myEndpoint/:id', {id:'@id'},{
'query':{
method:'GET',
cache:'true',
isArray:true
}}),
}
}]);