我试图找出一种方法来缓存我的knockoutJS SPA数据并且我一直在尝试使用amplifyJS。这是我的GET功能之一:
UserController.prototype.getUsers = function() {
var self = this;
return $.ajax({
type: 'GET',
url: self.Config.api + 'users'
}).done(function(data) {
self.usersArr(ko.utils.arrayMap(data.users, function(item) {
// run each item through model
return new self.Model.User(item);
}));
}).fail(function(data) {
// failed
});
};
这里有相同的功能,"放大":
UserController.prototype.getUsers = function() {
var self = this;
if (amplify.store('users')) {
self.usersArr(ko.utils.arrayMap(amplify.store('users'), function(item) {
// run each item through model
return new self.Model.User(item);
}));
} else {
return $.ajax({
type: 'GET',
url: self.Config.api + 'users'
}).done(function(data) {
self.usersArr(ko.utils.arrayMap(data.users, function(item) {
// run each item through model
return new self.Model.User(item);
}));
}).fail(function(data) {
// failed
});
};
这可以按预期工作,但我不确定我使用的方法,因为它还需要addUser
,removeUser
和editUser
函数的额外工作。看到我在我的应用程序中有更多类似的功能,我想尽可能避免额外的代码。
我已经找到了一种在ko.extenders
的帮助下处理事物的方法,如下所示:
this.usersArr = ko.observableArray().extend({ localStore: 'users' });
然后使用ko.extenders.localStore
函数在observableArray
内检测到更改时更新本地存储数据。所以在init上,如果observableArray
密钥存在本地存储数据,它将写入users
,并且在更改时它将更新本地存储数据。
我对这种方法的问题是我需要通过模型运行我的数据,而我无法通过localStore
函数找到一种方法来实现这一点,该函数保存在一个单独的页面上。 / p>
你们有没有和KO和Amplify合作过?你用了什么方法?我应该使用第一个还是尝试两者的组合并重写扩展器,使其只更新本地存储而无需在init上写入observableArray
?
答案 0 :(得分:1)
根据问题评论中的讨论,我建议使用本机HTTP缓存,而不是通过额外的库在客户端上添加另一个缓存层。
这需要实施条件请求方案。
这样的方案通过Last-Modified
(或E-Tag
)HTTP标头以及影响浏览器缓存的其他标头(如Cache-Control:
及其各种选项)依赖Ajax响应标头中的新鲜度信息)。
当随后请求相同的资源(URL)时,浏览器会透明地向服务器发送If-Modified-Since
(或If-None-Match
)标头。
如果客户的信息仍然是最新的,服务器可以使用HTTP 304 Not Modified
进行响应。这比从头开始重新创建完整响应快得多。
从Ajax请求的角度来看(jQuery或其他方式),响应的工作方式相同,无论它是来自服务器还是来自浏览器的缓存,后者只是快得多。
为此需要仔细调整服务器端,另一方面客户端不需要太多改动。
实现条件请求的好处是减少了服务器上的负载,并加快了客户端上的响应行为。
Knockout的一个特色是进一步改善这一点:
如果您碰巧使用mapping plugin将原始服务器数据映射到复杂视图模型,则可以定义 - 作为控制映射过程的选项的一部分 - key
函数。其目的是将视图模型的各个部分与源数据的各个部分进行匹配。
这样,已经映射的部分数据将不会再次映射,其他部分也会更新。这可以帮助减少客户端对已有数据的处理时间,并且可能还有不必要的屏幕更新。