ExtJS和复杂的保存操作

ExtJS 4.1.0

6/6/13更新

我已经在Sencha论坛上发布了同样的问题,在那里没有太多的行动。 这篇文章或多或少是一样的,但我想我会在这里添加它仅仅作为参考。 我仍然渴望听到其他社区成员对ExtJS应用程序中常见的情况的意见! http://www.sencha.com/forum/showthread.php?265358-Complex-Model-Save-Decoupling-Data-and-Updating-Related-Stores

2013年7月16日更新(结论?)

Sencha的帖子收到了很少的讨论。 我已决定将复杂保存操作的大部分负载放在我的应用程序服务器上,并在需要时懒惰地刷新客户端存储。 通过这种方式,我可以使用自己的数据库包装器来包含与一个复杂的域对象关联的所有事务,以保证原子性。 如果保存新Order包括保存订单元数据, OrderContents十个新实例和潜在的其他信息(驻留在其他表中的地址,创建订单时定义的新客户等),我宁愿将有效载荷发送给应用程序服务器,而不是在客户端应用程序代码中建立一个低俗的回调网络。 在Order.save()操作的success回调中更新一对一关联的数据(例如Order hasOne Address )。 更复杂的数据,比如Order的内容,只需简单地调用contentStore.sync()即可处理。 我觉得这是保证原子性的手段,不需要大量的客户端回调

原始发布内容

鉴于保存关联模型的整体令人失望的功能,我的应用程序中除了抛弃模型关联外,还依赖于自己检索关联的数据。 这一切都很好,但不幸的是不能解决实际保存数据和更新ExtJS存储以反映服务器上的更改的问题。

举例来说,保存一个Order对象,它由元数据以及OrderContents即订单上的部件)组成。 中的元数据的最终Order_Data在数据库表,而内容全部以最终Order_Contents其中每一行经由链接到父顺序表order_id列。

在客户端上,检索订单的内容很容易,不需要任何关联: var contents = this.getContentsStore().query('order_id', 10).getRange() 。 然而,一个主要的缺陷是, 这是对OrderContents ExtJS商店中可用的内容记录的OrderContents ,如果我使用的数据服务器不是由“主”对象返回的关联,这将适用。

在保存订单时,我发送一个保存订单元数据的单个请求(例如日期,订单号,供应商信息等)以及一系列内容。 这些数据被分开并保存到适当的表格中。 这对我来说意义重大,运作良好。

一切都很好,直到从应用程序服务器返回已保存/更新的记录。 由于通过调用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()是在store.sync()事件中不应将记录传递给应用程序服务器。

这种方法对我来说似乎有点sl / /哈克,但我还没有找到更好的解决方案......

任何输入/想法都非常感谢!


更新8/26/13我发现相关数据的确由Ext在模型代理的create / update回调中处理,但发现数据并不容易......请参阅我的帖子:ExtJS 4.1 - 返回关联数据Model.Save()响应

好吧,这个问题已经过去几个月了,我觉得这个问题没有神奇的解决方案。

我的解决方案如下...

当保存一个复杂的模型(例如一个模型,或者确实有一些hasMany关联)时,我保存包含所有相关数据的“父”模型(作为模型上的属性/字段!),然后添加保存)afterSave / afterUpdate回调中的关联数据。

就拿我PurchaseOrder哪个型号hasMany ItemshasOne Address 。 请注意,关联的数据包含在模型的属性中,因为如果它仅存在于模型的关联存储中,则不会将其传递到服务器。

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

我有Models的建立PurchaseOrder.ContentPurchaseOrder.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()回调混乱的字符串
  • 只有一个请求很容易管理
  • 原子性很容易在应用程序服务器上处理
  • 减少往返次数=减少潜在失败点
  • 如果你真的感觉懒惰,回调的success方法可以简单地reload商店。
  • 我会让这个答案坐下来鼓励讨论。

    谢谢阅读!

    链接地址: http://www.djcxy.com/p/76383.html

    上一篇: ExtJS and Complex Save Operations

    下一篇: Google Calendar Event GoogleAuthIOException