4

我有一个日历应用程序,它使用 ajax 和 json 结果加载所有事件数据。问题是我有不同的观点,现在当我改变观点时我必须重新调用服务器。

有什么方法可以让我在客户端缓存这些数据,并在触发更多 ajax 调用之前检查我是否已经加载了这些事件。

对此的最佳做法是什么?

4

3 回答 3

2

就像 hvgotcodes 所说,MVC 框架会有所帮助;例如,试试backbone.js (http://documentcloud.github.com/backbone/)。

或者,您可能要考虑使用 jStorage (http://www.jstorage.info/)。每次您需要进行 AJAX 调用时,首先检查它是否在您的存储对象中,如果不是,则运行 AJAX 调用。另一方面,无论何时完成 AJAX 调用,都将结果存储在存储对象中。确保在数据存储中查找时有某种索引(CalendarEvent id)可供参考。可能还想在存储中的数据中添加某种“过期时间”...... AJAX 调用之后的时间戳,如果它已经过时,则重新请求。

于 2011-12-09T00:36:58.850 回答
1

它被称为MVC。

您需要为您的应用程序构建一个数据模型,编写某种 Record 对象,然后您可以确定它们的状态。所以你的应用程序会有某种CalendarEvent模型,当你从服务器加载数据时,你会实例化实例。

因此,在更改视图时,您首先要检查是否有该视图的模型对象,如果有,则不需要从服务器加载它(除非您想检查更改)。

你的计划不需要那么复杂。如果您按 Id 加载事件,您可以执行类似的操作

window.App = {};
window.App.Models = {};

当您加载记录时,您可以放入

window.App.Models[id] = InstanceOfYourRecord

这样查找记录非常快。或者只是使用具有强大数据层的框架(如 Sproutcore)。

于 2011-12-09T00:24:30.507 回答
0

我在最近的一个项目中遇到了类似的问题。

从概念上讲,我将“真实”数据模型 (DM) 保存在服务器上,并保存到数据库中。

为了让生活更健康,客户端保留自己的本地数据模型。在客户端 DM 之外,所有客户端代码都认为它在本地提取结果。

从客户端 DM 读取数据 (GET) 时:

  • 检查缓存中的现有结果
  • 当缓存数据不可用时调用适当的 AJAX 查询,然后缓存结果。

通过客户端 DM 更改数据 (POST) 时:

  • 酌情使缓存无效
  • 调用适当的 AJAX 查询
  • 发出自定义 jQuery 事件,指示客户端 DM 已更改

请注意,此客户 DM 还:

  • 集中 AJAX 错误处理
  • 跟踪仍在进行中的 AJAX 调用。(让我们在离开未保存更改的页面时警告用户)。
  • 允许对单元测试进行插入式虚拟替换,其中所有调用都命中本地数据并且完全同步。

实施说明:

  • 我将其编码为一个名为 DataModel 的 JavaScript 类。随着设计变得越来越复杂,将职责进一步分解为单独的对象是有意义的。
  • jQuery 的自定义事件让您轻松实现观察者模式。每当指示数据已更改时,客户端组件都会从客户端 DM 进行自我更新。
  • 远程 API 中的 JSON 有助于简化代码。我的客户端 DM 将 JSON 结果直接存储在其缓存中。
  • 客户端 dm 函数参数包括回调,因此在需要时可以自然地通过 AJAX 传递所有内容:function listAll(contactId, cb) { ... }
  • 我的项目只允许单用户登录。如果外部各方可以更改服务器数据模型,则应定期触发某种 has-data-changed 探测以确保客户端缓存仍然有效。
  • 对于我的应用程序,多个客户端组件在接收到客户端 DM 更改事件时会请求相同的数据。这导致了多个具有相同信息的 AJAX 调用。我使用 getJsonOnce() 助手解决了这个问题,它管理等待相同结果的客户端组件回调队列。

我的实现中的示例函数:

listAll:
function( contactId, cb ) {

  // pull from cache
  if ( contactId in this.notesCache ) {
    cb( this.notesCache[contactId] );
    return;
  }

  // init queue if needed
  this.listAllQueue[contactId] = this.listAllQueue[contactId] || [];

  // pull from server
  var self = this;
  dataModelHelpers.getJsonOnce(
    '/teafile/api/notes.php',
    {'req': 'listAll', 'contact': contactId},
    function(resp) { self.notesCache[contactId] = resp; },
    this.listAllQueue[contactId],
    cb
  );
}

getJsonOnce() 帮助器确保如果多个客户端组件请求完全相同(未缓存的)数据,我们只发送一个 AJAX 请求并在它进入时通知每个人。

notesCache 只是一个简单的 javascript 对象:

this.notesCache = {};
于 2011-12-09T00:24:36.010 回答