Search code examples
javascriptextjsextjs4model-associations

ExtJS Automatically populating a model property via an association


I am using ExtJS 4.1.0

Say I have a couple simple model's connected via a hasMany association. The models represent an order and order contents...

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.. */

});

Now, what if I want the contents property of my App.model.Order to be automatically set when an Order model is instantiated? For a temporary solution, I have added the following method to the Order model:

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

/** Model definition ... */

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

    }
});

In order to have an Order object with contents readily available, I must do the following:

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

I have tried overloading the constructor for App.model.Order but no matter what, I cannot get access to the data loaded by the association even if I perform a callback on the async request for the association data.

Ultimately I would like to be able to retrieve an Order from my App.store.Orders and have the retrieved record already have its contents property set, but I just can't figure it out! If I retrieve a record from the store as follows:

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

I'm really just trying to cut down on having to .loadContents() for every instance of App.model.Order throughout my application; this seems like it should be very easy to accomplish. What am I missing?!

Thanks for your time!


Solution

  • I managed a workaround by overloading the store's constructor:

    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);
        }
    });
    

    Hopefully this will help someone :)