6

第一:我意识到这里有人问过这个问题:在 ExtJS 中,调用 Model.save() 还是 Store.Sync() 更好?- 但是我希望进一步研究这一点,特别是关于最大限度地减少客户端和服务器上的 XHR 和不必要的开销。我认为链接问题中没有解决这些问题。

我有一个为企业资源管理设计的大型应用程序,由许多模型、视图和控制器组成。我通过建立 Ext.AjaxrequestCompleterequestException事件的侦听器来处理来自服务器的所有响应。我采用了这种方法,而不是在每个模型的代理事件上编写重复的事件处理程序afterRequest。这使我能够让我的所有后端(使用 Zend 框架)控制器响应三个参数successmessagedata.

在成功请求(即 HTTP 200)后,run for 方法requestComplete将检查 JSON 响应中的上述参数。如果successfalse,则预计将包含一条错误消息message,然后将其显示给用户(例如,“保存该产品时出现问题。产品名称无效”)。如果成功为真,则根据请求的类型采取行动,即创建、读取、更新或销毁。成功后create,新记录被添加到适当的数据存储中,删除后记录被销毁,依此类推。

我选择采用这种方法,而不是向商店添加记录并调用商店的sync方法,以最小化 XHR 和其他往返行程。我目前保存/更新数据的方法是将请求发送到后端并在 Ext 前端对结果做出反应。为此,我使用数据填充模型并调用 model.save() 来创建/更新请求,或者调用 model.destroy() 来删除数据。

我发现当从存储中添加/更新/删除记录,然后调用 store.sync() 时,我必须以一种感觉尴尬的方式对服务器的响应做出反应。以删除记录为例:

  1. 首先,通过以下方式从存储中删除记录store.remove()
  2. store.sync()在我将商店autoSync设置为 时调用false
  3. 这会触发来自商店模型代理的 AJAX 销毁请求。
  4. 这就是它变得奇怪的地方......如果从数据库中删除行时服务器上出现错误,则响应将返回success: false,但是记录已经从 ExtJS 数据存储中删除。
  5. 在这一点上,我可以调用store.sync(), store.load()(两者都需要往返)或从请求中获取记录并将其添加回存储区,后跟 acommitChanges()以避免调用额外的同步/加载,从而避免不必要的往返。

添加记录也是如此,如果在向数据库添加数据时服务器在某处发生故障,则该记录仍在 ExtJS 存储中,必须手动删除以避免与store.sync()or的往返store.load()

为了避免整个问题,正如我之前解释的那样,我实例化了我的一个模型对象(例如 Product 模型),用数据填充它,然后调用myModel.save(). 这反过来调用代理的createupdate取决于模型的 ID,并触发适当的 AJAX 请求。如果后端发生故障,前端存储仍然保持不变。在成功的请求(读取:success: true,而不是 HTTP 200)上,我手动将记录添加到 store 并调用store.commitChanges(true),有效地将 store 与数据库同步,而无需额外的往返行程并避免不必要的开销。对于所有请求,服务器将使用新的/修改的数据以及成功参数进行响应,并有条件地在客户端上显示一条消息。

我在这里遗漏了什么,还是这种方法是最小化 XHR 和服务器/客户端开销的好方法?如果需要,我很乐意提供示例代码,但是我觉得这是一个包含基本代码的相当笼统的概念。

4

1 回答 1

2

I think you have eloquently argued your position. I don't see anything wrong with the position you have taken. My only reproach is to point out that autoSync setting on a store that backs editable grid is a far less verbose way of accomplishing the task, albeit with less control.

To add, the overhead which you point out is typically due to the unexpected or I would call edge cases that may need special handling or an extra refresh of data. You could add listeners for those specific cases and leave the rest functioning with terse defaults.

于 2012-10-31T17:50:54.547 回答