我正在尝试找出一种方法来缓存我的 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' });
然后,只要检测到 observableArray
内部发生更改,就使用 ko.extenders.localStore 函数更新本地存储数据。因此,在初始化时,如果 users
键存在本地存储数据,它将写入 observableArray
,并且在发生更改时,它将更新本地存储数据。
这种方法的问题是,我需要通过模型运行数据,但我无法从 localStore
函数中找到执行此操作的方法,该函数保存在单独的页面上。
你们中有人与 KO 和 Amplify 合作过吗?你用了什么方法?我应该使用第一个还是尝试结合两者并重写扩展器,使其仅更新本地存储而不写入 init 上的 observableArray
?
最佳答案
根据问题评论中的讨论,我建议使用 native HTTP 缓存,而不是通过额外的库在客户端添加另一个缓存层。
这需要实现条件请求方案。
这样的方案依赖于 Ajax 响应 header 中的新鲜度信息,通过 Last-Modified
(或 E-Tag
)HTTP header 和其他影响浏览器缓存的 header (就像 Cache-Control:
及其各种选项)。
当同一资源 (URL) 被访问时,浏览器会透明地向服务器发送
If-Modified-Since
(或If-None-Match
) header 。随后提出要求。如果客户端的信息仍然是最新的,服务器可以使用 HTTP
304 Not Modified
进行响应。这比从头开始重新创建完整响应要快得多。从 Ajax 请求的 Angular (jQuery 或其他方式)来看,响应的工作方式是相同的,无论它实际上来自服务器还是来自浏览器的缓存,后者只是快得多.
为此需要仔细调整服务器端,而客户端则不需要太多更改。
实现条件请求的好处是减少服务器上的负载并加快客户端的响应行为。
Knockout 的特色可以进一步改进这一点:
如果您碰巧使用mapping plugin要将原始服务器数据映射到复杂的 View 模型,您可以定义 - 作为控制映射过程的选项的一部分 - key
函数。其目的是将 View 模型的部分与源数据的部分进行匹配。
这样已经映射的部分数据将不会再次映射,其他数据会被更新。这有助于减少客户端处理已有数据的时间,并可能减少不必要的屏幕更新。
关于javascript - 使用 Amplify JS 存储 Knockout JS 模型数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24658584/