ExtJS 和复杂的保存操作 [英] ExtJS and Complex Save Operations

查看:28
本文介绍了ExtJS 和复杂的保存操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ExtJS 4.1.0

2013 年 6 月 6 日更新:

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

I have posted this same question on the Sencha forums where there hasn't been much action. The post is more or less the same, but I figured I would add it here just for reference. I am still eager to hear other community members' input on what must be a very common scenario in an ExtJS Application! http://www.sencha.com/forum/showthread.php?265358-Complex-Model-Save-Decoupling-Data-and-Updating-Related-Stores

更新 7/16/13(结论?)

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

The Sencha post garnered very little discussion. I have decided to put the majority of the load of complex save operations on my application server and lazily refresh client stores where need be. This way I can use my own Database wrapper to encompass all of the transactions associated with one complex Domain Object save to guarantee atomicity. If saving a new Order consists of saving the order metadata, ten new instances of OrderContents and potentially other information (addresses residing in other tables, a new customer defined at the time of order creation, etc.) I would much rather send the payload to the application server, rather than establish a vulgar web of callbacks in client-side application code. Data which is associated on a One-to-One basis (such as an Order hasOne Address) is updated in the success callback of the Order.save() operation. More complex data, such as the Order's contents, is lazily handled by simply calling contentStore.sync(). I feel that this is the means to guarantee atomicity without an overwhelming number of client-callbacks

原始帖子内容

鉴于保存关联重模型的整体功能令人失望,我几乎放弃了应用程序中的模型关联,并依靠自己检索关联数据.这一切都很好,但遗憾的是并没有解决实际保存数据和更新 ExtJS 存储以反映服务器上的更改的问题.

Given the overall disappointing functionality of saving association-heavy models, I have all but ditched model associations in my application and rely retrieving associated data myself. This is all well and good, but unfortunately does not resolve the issue of actually saving the data and updating ExtJS stores to reflect the changes on the server.

以保存一个Order对象为例,它由元数据和OrderContents即订单上的部分组成.元数据在数据库中的 Order_Data 表中结束,而内容都在 Order_Contents 表中结束,其中每一行都通过 链接到父订单order_id 列.

Take for example saving an Order object, which is composed of metadata as well as OrderContents i.e., the parts on the order. The metadata ends up in an Order_Data table in the database, whereas the contents all end up in an Order_Contents table where each row is linked to the parent order via an order_id column.

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

On the client, retrieving the contents for an order is quite easy to do without any need for associations: var contents = this.getContentsStore().query('order_id', 10).getRange(). However, a major flaw is that this is hinging on the content records being available in the OrderContents ExtJS Store, which would apply if I were using associations NOT returned by the data server with the "main" object.

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

When saving an order, I send a single request which holds the order's metadata (e.g., date, order number, supplier information, etc.) as well as an array of contents. These pieces of data are picked apart and saved to their appropriate tables. This makes enough sense to me and works well.

一切都很好,直到从应用程序服务器返回保存/更新的记录.由于请求是通过调用 OrderObject.save() 触发的,因此没有任何信息告诉 OrderContents 存储新记录可用.如果我将记录添加到存储并调用 .sync(),这将自动处理,但我觉得这会使保存过程复杂化,我宁愿在应用程序服务器上处理这种解耦更不用说,保存整个请求也很不错.

All is well until it comes to returning saved/updated records from the application server. Since the request is fired off by calling a OrderObject.save(), there is nothing telling the OrderContents store that new records are available. This would be handled automatically if I were to instead add records to the store and call .sync(), but I feel this complicates the saving process and I would just much rather handle this decoupling on the application server not to mention, saving an entire request is quite nice as well.

有没有更好的方法来解决这个问题?我目前的解决方案如下...

Is there a better way to solve this? My current solution is as follows...

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() 事件中不应将记录传递给应用程序服务器.

By calling commitChanges() the records added to the store are considered to be clean (non-phantom, non-dirty) and thus are no longer returned by the store's getModifiedRecords() method; rightly so as the records should not be passed to the application server in the event of a store.sync().

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

This approach just seems kinda sloppy/hacky to me but I haven't figured out a better solution...

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

Any input / thoughts are greatly appreciated!

推荐答案

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

Update 8/26/13 I found that associated data is indeed handled by Ext in the create/update callback on the model's proxy, but finding that data wasn't easy... See my post here: ExtJS 4.1 - Returning Associated Data in Model.Save() Response

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

Well, it's been a couple months of having this question open and I feel like there is no magically awesome solution to this problem.

我的解决方法如下...

My solution is as follows...

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

When saving a complex model (e.g., a model that would, or does have a few hasMany associations), I save the 'parent' model which includes all associated data (as a property/field on the model!) and then add the (saved) associated data in the afterSave/afterUpdate callback.

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

Take for example my PurchaseOrder model which hasMany Items and hasOne Address. Take note that the associated data is included in the model's properties, as it will not be passed to the server if it solely exists in the model's association store.

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.ContentPurchaseOrder.Address 建立了Models,但PurchaseOrder 中的数据不是这些模型的实例,而只是数据.同样,这是为了确保将其正确传递到应用服务器.

I have Models established for PurchaseOrder.Content and PurchaseOrder.Address, yet the data in the PurchaseOrder is not an instance of these models, rather just the data. Again, this is to ensure that it is passed correctly to the application server.

一旦我有了一个如上所述的对象,我就通过 .save() 将它发送到我的应用服务器,如下所示:

Once I have an object like described above, I send it off to my application server via .save() as follows:

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).

My application server receives the PurchaseOrder and handles saving the data accordingly. I will not go into gross details as this process is largely dependent on your own implementation. My application framework is loosely based on Zend 1.11 (primarily leveraging Zend_Db).

我认为这是最好的方法,原因如下:

I feel this is the best approach for the following reasons:

  • 客户端没有各种model.save()回调的杂乱字符串
  • 只有一个请求,非常容易管理
  • 在应用服务器上很容易处理原子性
  • 更少的往返次数 = 更少的潜在故障点
  • 如果你真的很懒,回调的success方法可以简单地reload存储.
  • No messy string of various model.save() callbacks on the client
  • Only one request, which is very easy to manage
  • Atomicity is easily handled on the application server
  • Less round trips = less potential points of failure to worry about
  • If you're really feeling lazy, the success method of the callback can simply reload stores.

为了鼓励讨论,我会让这个答案停留一会儿.

I will let this answer sit for a bit to encourage discussion.

感谢阅读!

这篇关于ExtJS 和复杂的保存操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆