2

For example I have 2 models:

Ext.define('Order', {
    extend   : 'Ext.data.Model',
    fields   : [
            {name : 'id',          type : 'int'},
            {name : 'customer_id', type : 'int'},
            {name : 'date',        type : 'date'}
    ],
    hasMany: [{model: 'Product', name: 'Products'}]
});

Ext.define('Product', {
    extend   : 'Ext.data.Model',
    fields   : [
            {name : 'id',          type : 'int'},
            {name : 'name',        type : 'string'},
            {name : 'description', type : 'string'},
            {name : 'price',       type : 'float'}
    ],
    belongsTo: 'Order'
});

these models displayed in 2 grids. Then when changes made I need post them to server. But the trick in I need post both model in one request, e.g.:

{"order":{"id":1, "date":'2011.09.01', "Products": [{"id":1, "name":"product name", ... }]}}

In this way I think both grids should use one Store and before write store in must be filled with grid changes ( maybe some internal stores without ability to write to server ).

How to implement it ? Any ideas ?

mastak
  • 1,397
  • 1
  • 14
  • 28

2 Answers2

2

The solution is store data in memory and on Save fill synced store manually and call Save method:

Ext.define('OrderStore', {
    extend: 'Ext.data.Store',

    storeId: 'orderStore',
    proxy: {
        type: 'ajax',
        api: {
            read: 'Order/Load',
            create: 'Order/Add',
            update: 'Order/Update',
            destroy: 'Order/Delete'
        },
        reader: {
            type: 'json',
            root: 'orders',
            totalProperty: 'total',
            messageProperty: 'message',
            successProperty: 'success'
        },
        writer: {
            type: 'json',
            listful: true,
            writeAllFields: true,
                    getRecordData: function (record) { return record.data; },
            root: 'order',
            allowSingle: true
        },
        headers: { 'Content-Type': 'application/json; charset=UTF-8' }
    },
    autoLoad: true,
    listeners: {
        // commit changes
        write: function (store, operation, eOpts ) {
            var orderItemsStore = OrderEdit.store;
            orderItemsStore.each( function (item) {
                item.commit();
            });

            // ...
        }
    }
});

where:

Ext.define('OrderEdit', {
    // ...
    orderStore: Ext.create('OrderStore', {model: 'Order', owner: this}),
    store: Ext.create('OrderItemStore')

and

Ext.define('OrderItemStore', {
    extend: 'Ext.data.Store',

    model: 'Order',
    proxy: {
        type: 'memory'
    }
});

and then save changes:

saveButtonClick: function (button) {
    var order = OrderEdit.orderStore.getRange()[0];
    res = order.data;
    res.Items = [];
    OrderEdit.store.each(function (record, index) {
            res.Items[index] = record.data;
    });
    // ...

    OrderEdit.orderStore.removeAll();
    OrderEdit.orderStore.add(res);
    OrderEdit.orderStore.save();
}
mastak
  • 1,397
  • 1
  • 14
  • 28
1

I have tackled the same problem by creating a custom Writer (extending Ext.data.writer.Json in my case). In your scenario this would used as the writer for the Order store. My Product store is read only (I never sync it with the server).

My writer overrides the getRecordData() function. First it performs the standard getRecordData() processing to get the Order data, it then iterates over the Product store's entries to create an array of product records. I then add this array to the order's data (with a key of 'Products'.

Paul M
  • 357
  • 1
  • 8
  • 2
    well.. I have implemented it in another way: build Ajax request with grids data changes to server. All works fine, except one thing. After data successfully updated I need to tell grid to redraw and refresh it store, means remove updated / created records from store ( changes displayed as red rectangles in cells top left corner ) :(... – mastak Sep 01 '11 at 13:24