javascript - ExtJS 和复杂的保存操作

标签 javascript model-view-controller extjs orm extjs4

ExtJS 4.1.0

13 年 6 月 6 日更新 :

我在 Sencha 论坛上发布了同样的问题,那里没有太多的行动。该帖子或多或少相同,但我想我会在这里添加它仅供引用。我仍然渴望听到其他社区成员对 ExtJS 应用程序中必须是非常常见的场景的意见!
http://www.sencha.com/forum/showthread.php?265358-Complex-Model-Save-Decoupling-Data-and-Updating-Related-Stores

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

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

原帖内容

考虑到保存关联重模型的整体令人失望的功能,我在我的应用程序中几乎抛弃了模型关联,并依靠自己检索关联数据。这一切都很好,但不幸的是并没有解决实际保存数据和更新 ExtJS 存储以反射(reflect)服务器上的更改的问题。

以保存 Order 为例对象,由元数据和 OrderContents 组成即订单上的零件。元数据以 Order_Data 结尾数据库中的表,而所有内容都以 Order_Contents 结尾表中的每一行都通过 order_id 链接到父订单柱子。

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

保存订单时,我发送一个请求,其中包含订单的元数据(例如,日期、订单号、供应商信息等)以及一系列内容。这些数据被挑选出来并保存到相应的表中。这对我来说很有意义并且效果很好。

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

这种方法对我来说似乎有点草率/hacky,但我还没有想出更好的解决方案......

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

最佳答案

13 年 8 月 26 日更新 我发现关联数据确实是由 Ext 在模型代理的创建/更新回调中处理的,但是找到这些数据并不容易...请参阅我的帖子:ExtJS 4.1 - Returning Associated Data in Model.Save() Response

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

我的解决方法如下...

当保存一个复杂的模型(例如,一个模型有或确实有几个 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

我有 ModelsPurchaseOrder.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()回调的杂乱字符串
  • 只有一个请求,非常好管理
  • 原子性在应用服务器上很容易处理
  • 更少的往返次数 = 更少的潜在故障点
  • 如果你真的很懒惰,success回调方法可以简单地reload商店。

  • 我会让这个答案坐一会儿以鼓励讨论。

    谢谢阅读!

    关于javascript - ExtJS 和复杂的保存操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16551901/

    相关文章:

    javascript - 使用 Angular 2 在 HTML5 中动态定义输入类型

    javascript - typescript 编译器 : @types/d3-tip - Cannot invoke an expression whose type lacks a call signature

    javascript - 缩放 Canvas 上的鼠标位置

    c# - 验证所需的两个字段之一

    javascript - Ajax - 了解文件下载是否从服务器正确发送

    javascript - 动态加载 javascript,检查所有 javascript 何时加载

    PHP 最佳实践 : Im loading the $GLOBALS array with a lot of information to be shared between my php pages

    python - Django:通过外键查找所有反向引用

    javascript - Extjs 6 : What's the best practice to handle repeated configuration

    c# - Handler.ashx C# 到 Java、基于 ExtJs 的 TinyMCE 文件和图像管理器插件