Javascript ExtJS通过关联自动填充模型属性

Javascript ExtJS通过关联自动填充模型属性,javascript,extjs,extjs4,model-associations,Javascript,Extjs,Extjs4,Model Associations,我正在使用ExtJS 4.1.0 假设我有一对简单的模型通过一个关联连接起来。模型表示订单和订单内容 Ext.define('App.model.Order', { extend: 'Ext.data.Model', fields: ['id', 'order_date', 'order_total', 'contents' ], associations: [{ type : 'hasMany', m

我正在使用ExtJS 4.1.0

假设我有一对简单的模型通过一个
关联连接起来。模型表示订单和订单内容

Ext.define('App.model.Order', 
{
    extend: 'Ext.data.Model',
    fields: ['id', 'order_date', 'order_total', 'contents' ],
    associations: [{
            type           : 'hasMany',
            model          : 'App.model.OrderContents',
            name           : 'getContents', /** magic method */
            primaryKey     : 'id',
            foreignKey     : 'order_id',
            autoLoad       : false
    }],

    /** Proxy Definition here.. */

});

Ext.define('App.model.OrderContents', 
{
    extend: 'Ext.data.Model',
    fields: ['id', 'order_id', 'item_id' ],

    /** Proxy Definition here.. */

});
现在,如果我想在实例化
Order
模型时自动设置我的
App.model.Order
contents
属性,该怎么办?对于临时解决方案,我在
Order
模型中添加了以下方法:

Ext.define('App.model.Order', 
{

/** Model definition ... */

    loadContents: function()
    {
       this.getContents().load({
            callback: function()
            {
                this.set('contents', arguments[0]);
            },
            scope: this
        });

    }
});
为了使
order
对象的内容随时可用,我必须执行以下操作:

var myOrder = new App.model.Order({id:1, order_date:'12-15-2012', order_total:100});
myOrder.getData(true); // contents will be null
myOrder.loadContents();
myOrder.getData(); // contents will be an array of OrderContents
我已尝试重载App.model.Order的构造函数,但无论如何,即使对关联数据的异步请求执行回调,我也无法访问关联加载的数据

最终,我希望能够从我的
App.store.Orders
中检索订单,并使检索到的记录已经设置了其
内容
属性,但我就是想不出来!如果我从存储中检索记录,如下所示:

myStore = Ext.getStore('OrderStore');
myOrder = myStore.findRecord('id',1);
myOrder.getData(); // contents will be null
myOrder.loadContents();
myOrder.getData(); // contents will be an array of OrderContents
我只是想减少在整个应用程序中对
App.model.Order
的每个实例执行
.loadContents()
;这看起来应该很容易做到。我错过了什么


谢谢你的时间

这没有经过测试,但应该可以使用

Ext.define('App.model.Order', 
{
    extend: 'Ext.data.Model',
    fields: ['id', 'order_date', 'order_total', 'contents' ],
    associations: [{
            type           : 'hasMany',
            model          : 'App.model.OrderContents',
            name           : 'getContents', /** magic method */
            primaryKey     : 'id',
            foreignKey     : 'order_id',
            autoLoad       : false
    }],
    load: function(id, config) {
            config = Ext.apply({
                  success: function(record, operation) {
                        store.getContents().load();
                  },
            }, config);
            this.callParent([id, config]);
    },
    /** Proxy Definition here.. */

});
更新: 您可以编写自己的加载方法(在本例中称为loadAll),如下所示:

    Ext.define('App.model.OrderContents', 
    {
         extend: 'Ext.data.Model',
         fields: ['id', 'order_id', 'item_id' ],

         proxy: {
                type: 'memory',
                data: [
                    {id: 1, order_id: 1, item_id: 2}, 
                    {id: 2, order_id: 1, item_id: 3},
                    {id: 3, order_id: 21, item_id: 3}
                ],
              reader: 'json'            
         }

    });


    Ext.define('App.model.Order', 
         {
              extend: 'Ext.data.Model',
              fields: ['id', 'order_date', 'order_total', 'contents' ],
              associations: [{
                         type           : 'hasMany',
                         model          : 'App.model.OrderContents',
                         name           : 'getContents', /** magic method */
                         primaryKey     : 'id',
                         foreignKey     : 'order_id',
                         autoLoad       : false
              }],
              statics: {
                      loadAll: function(id, config) {
                         config = Ext.apply({
                                 callback: function(record, operation) {
                                     if(operation.wasSuccessful()){
                                        record.getContents().load();
                                        record.set('contents', record.getContents().getRange());
                                         }
                               },
                                scope: this
                         }, config);
                         App.model.Order.load(id, config);
                    }
              },
              proxy: {
                    type: 'memory',
                    data: {'id':1, 'order_date':null, 'order_total': 100, 'contents':[]},
                    reader: {
                        type: 'json'
                    }

              }
         });


var order;
App.model.Order.loadAll(1,{
    success: function(record){
        order = record;
    }
    });

console.log(order);
​您可以看到它在JSFIDLE上工作:


你提到你用Constructor试过,但我认为你做错了什么。如果您的构造函数如下所示:

constructor: function(){
    var me = this;
    me.callParent([arguments]);
    me.loadContents();
}

我想你会得到想要的结果…

我通过重载商店的构造函数来解决问题:

Ext.define('App.store.Orders', {
    extend: 'Ext.data.Store',
    storeId: 'OrdersStore',
    model: 'App.model.Order',

    constructor: function()
    {
        this.superclass.constructor.call(this);
        this.on('load', function(store, records, success, eOpts){
            Ext.each(records, function(order){
               order.loadContents();
            });
        }, this);
    }
});

希望这会对某人有所帮助:)

我或多或少地尝试过这种方法。尝试调用
loadContents
时,我收到一个错误“无法调用未定义的方法”call“。我已经解决了一个问题,请参阅我下面的评论。我重载了存储构造函数。我不相信该模型引发了
load
事件?很抱歉@lontivero的响应太慢,这看起来确实是一个优雅的解决方案。出于我的需要,我重载了包含我的订单的商店的构造函数。该方法对每个加载的记录进行迭代,并调用my
loadContents
方法,该方法依次按预期填充对象的
contents
属性。反过来,每当我从订单的存储中检索订单时,它将已经加载了其内容。再次感谢您的见解和解决方案!