更新6/6/13:
我在没有太多行动的Sencha论坛上发布了同样的问题.这个帖子或多或少是一样的,但是我想我会把它添加在这里供参考.我仍然渴望听到其他社区成员对ExtJS应用程序中一个非常常见的情况的投入!
http://www.sencha.com/forum/showthread.php?265358-Complex-Model-Save-Decoupling-Data-and-Updating-Related-Stores
7/16/13更新(结论?)
Sencha职位获得了很少的讨论.我决定将大部分复杂的保存操作加载到我的应用服务器上,并在需要的地方懒洋洋地刷新客户端商店.这样我可以使用我自己的数据库包装器来包含与一个复杂的域对象关联的所有事务保存以保证原子性.如果保存新的订单包括保存订单元数据,则可能会有10个OrderContent的新实例和潜在的其他信息(驻留在其他表中的地址,订单创建时定义的新客户等),我宁愿将有效负载发送到应用服务器,而不是在客户端应用程序代码中建立一个粗俗的回调网络.在Order.save()操作的成功回调中更新了一对一关联的数据(例如Order hasOne Address).更简单的数据,例如Order的内容,通过简单地调用contentStore.sync()来处理.我觉得这是保证原子性的手段,而没有压倒多数的客户回调
原始帖子内容
鉴于存储关联重型模型的整体令人失望的功能,我在我的应用程序中除了丢弃了模型关联,并且依赖于自己检索相关数据.这一切都很好,但遗憾的是并不能解决实际保存数据和更新ExtJS存储以反映服务器上更改的问题.
例如保存由元数据以及OrderContents(即订单上的部分)组成的Order对象.元数据最终在数据库中的Order_Data表中,而内容全部在Order_Contents表中,其中每一行都通过order_id列链接到父级顺序.
在客户端,检索订单的内容是很容易的,而不需要关联:var contents = this.getContentsStore().query(‘order_id’,10).getRange().然而,一个主要的缺陷在于这取决于OrderContents ExtJS Store中提供的内容记录,如果我使用数据服务器没有返回的关联与“主”对象的关联,这将适用.
保存订单时,我发送一个持有订单的元数据(例如日期,订单号,供应商信息等)的请求以及内容数组.将这些数据片段分开并保存到其适当的表格中.这对我来说足够有意义,运作良好.
一直很好,直到从应用程序服务器返回保存/更新的记录.由于通过调用OrderObject.save()来触发该请求,所以没有任何告诉OrderContents存储新记录可用.这将自动处理,如果我要添加记录到商店并调用.sync(),但我觉得这使得保存过程复杂化,我只会在应用程序服务器上更多地处理这种解耦,更不用说,保存整个请求也是很好的.
var orderContentsStore = this.getOrderContentsStore(); MyOrderObject.save({ success: function(rec,op){ // New Content Records need to be added to the contents store! orderContentsStore.add(rec.get('contents')); // Array of OrderContent Records orderContentsStore.commitChanges(); // This is very important } });
通过调用commitChanges(),添加到商店的记录被认为是干净的(非幻像,非脏),因此不再由商店的getModifiedRecords()方法返回;正确地,在store.sync()的情况下不应将记录传递给应用程序服务器.
这个方法对我来说似乎有点马虎虎虎,但是我并没有想出更好的解决方案
任何输入/想法非常感谢!
解决方法
那么这个问题已经开了好几个月,我觉得这个问题没有什么神奇的解决方案.
我的解决方案如下:
当保存一个复杂的模型(例如,一个模型,或者有几个具有很多关联的模型)时,我保存包含所有相关数据(作为模型上的属性/字段)的“父”模型,然后添加保存)afterSave / afterUpdate回调中的关联数据.
以我的PurchaSEOrder模型为例,它具有多个项目并具有一个地址.请注意,相关数据包含在模型的属性中,因为如果它仅存在于模型的关联存储中,则不会将其传递到服务器.
console.log(PurchaSEOrder.getData()); --- id: 0 order_num: "PO12345" order_total: 100.95 customer_id: 1 order_address: Object id: 0 ship_address_1: "123 Awesome Street" ship_address_2: "Suite B" ship_city: "Gnarlyville" ship_state: "Vermont" ship_zip: "05401" ...etc... contents: Array[2] 0: Object id: 0 sku: "BR10831" name: "Super Cool Shiny Thing" quantity: 5 sold_price: 84.23 1: Object id: 0 sku: "BR10311" name: "Moderately Fun Paddle Ball" quantity: 1 sold_price: 1.39
我有为PurchaSEOrder.Content和PurchaSEOrder.Address建立的模型,但PurchaSEOrder中的数据不是这些模型的实例,而是数据.同样,这是为了确保它被正确地传递给应用服务器.
一旦我有一个如上所述的对象,我通过.save()将它发送到我的应用程序服务器,如下所示:
PurchaSEOrder.save({ scope: me,success: me.afterOrderSave,failure: function(rec,op){ console.error('Error saving Purchase Order',op); } }); afterOrderSave: function(record,operation){ var me = this; switch(operation.action){ case 'create': /** * Add the records to the appropriate stores. * Since these records (from the server) have an id,* they will not be marked as dirty nor as phantoms */ var savedRecord = operation.getResultSet().records[0]; // has associated! me.getOrderStore().add(savedRecord); me.getOrderContentStore().add(savedRecord.getContents()); //association! me.getOrderAddressStore().add(savedRecord.getAddress()); // association! break; case 'update': // Locate and update records with response from server break; } }
我的应用程序服务器接收到PurchaSEOrder并处理相应的保存数据.我不会详细介绍,因为这个过程很大程度上取决于你自己的实现.我的应用程序框架松散地基于Zend 1.11(主要利用Zend_Db).
我认为这是最好的方法,原因如下:
>客户端上没有各种各样的model.save()回调的乱码字符串
>只有一个请求,这很容易管理
>原子性很容易在应用服务器上处理
>较少的往返行程=较少潜在的失败点担心
>如果你真的很懒,回调的成功方法可以简单地重新加载商店.
我会让这个答案坐下来鼓励讨论.
谢谢阅读!