6

I have a list of grids that can change their data in form by end-user. Finally, I want to sync all the grids by clicking the button, then an operation is performed.

I wrote the code below:

$.when.apply(
    Ext.ComponentQuery.query('grid')
       .forEach(function(item) {
             if (item.getXType() == "grid") {
                if (item.store.getNewRecords().length > 0 || item.store.getUpdatedRecords().length > 0 || item.store.getRemovedRecords().length > 0) {
                    item.store.sync();
                 }
             }
})).then(function (results) {
    //do something
});

Problem is here that store.sync() not waiting for callback.

What is the recommended way of doing this?

Hossein
  • 3,083
  • 3
  • 16
  • 33
  • `store.sync()` should not be required, to begin with... use config `autoSync: true`. – Martin Zeitler Sep 15 '18 at 15:27
  • @MartinZeitler I have alot of data in grid and dont want to send request for each cell edit. – Hossein Sep 16 '18 at 05:16
  • it would only sync the one row, which had changed - while a user won't change more than one row at a time - this barely would be more traffic, only split into more requests. in times, where people tend to have > 100mbit/s, even at home. – Martin Zeitler Sep 16 '18 at 09:34
  • @MartinZeitler I do it with `Promise` , Anyway thank you. – Hossein Sep 16 '18 at 09:37
  • @MartinZeitler `autoSync` changes the behaviour of the program. Not sure why you recommend that. Would you want Excel to automatically save all your changes without asking? – Alexander Sep 16 '18 at 12:45

2 Answers2

5

I do it with Promise like this:

 // Sync grid data if exist dirty data
 Promise.all(
     Ext.ComponentQuery.query('grid')
     .map(grid => grid.getStore())
     .filter(s => (s.getNewRecords().length + s.getUpdatedRecords().length + s.getRemovedRecords().length) > 0)
     .map(s => new Promise((resolve, reject) => {
           s.sync({
               success: () => { resolve(); },
               failure: () => { reject(); }
           });
      }))
      ).then(() => {
           //do something
      });
Hossein
  • 3,083
  • 3
  • 16
  • 33
2

You could use callback for your store.sync() method.

The callback function to be called upon completion of the sync. The callback is called regardless of success or failure and is passed the following parameters: (batch, options).

You could achieve your requirement like this

  1. Take a blank array name before loop. like this var gridIds=[].

  2. In side of loop before store.sync() push grid id in above array.

  3. Now in callback function remove that grid id from above array and check condition array is blank then your all store sync response has came.

You can check here with working Fiddle

Note I have used dummy api. Please use your actual api.

CODE SNIPPET

Ext.application({
    name: 'Fiddle',

    launch: function () {

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

            alias: 'store.mystore',

            fields: ['name'],

            autoLoad: true,

            pageSize: 25,

            remoteSort: true,

            proxy: {
                type: 'ajax',
                method: 'POST',
                api: {
                    read: 'data.json',
                    update: 'your_update_api',
                    create: 'your_create_api',
                    destroy: 'your_delete_api'
                },
                reader: {
                    type: 'json'
                },
                writer: {
                    type: 'json',
                    encode: true,
                    root: 'data'
                }
            },
        });

        Ext.define('MyGrid', {

            extend: 'Ext.grid.Panel',

            alias: 'widget.mygrid',

            store: {
                type: 'mystore'
            },

            height: 200,

            border: true,

            tools: [{
                xtype: 'button',
                iconCls: 'fa fa-plus-circle',
                tooltip: 'Add New Record',
                handler: function () {
                    let grid = this.up('grid'),
                        store = grid.getStore();

                    store.insert(0, {
                        name: 'Test ' + (store.getCount() + 1)
                    });
                }
            }],
            columns: [{
                text: 'Name',
                dataIndex: 'name',
                flex: 1
            }]
        });

        Ext.create({
            xtype: 'panel',
            // title: 'Store sync example',

            items: [{
                xtype: 'mygrid',
                title: 'Grid 1'
            }, {
                xtype: 'mygrid',
                title: 'Grid 2'
            }, {
                xtype: 'mygrid',
                title: 'Grid 3'
            }, {
                xtype: 'mygrid',
                title: 'Grid 4'
            }],

            bbar: ['->', {
                text: 'Submit Changes',
                handler: function (btn) {
                    var panel = btn.up('panel'),
                        grids = panel.query('grid'),
                        gtidIds = [],
                        lenthCheck = function (arr) {
                            return arr.length > 0;
                        };

                    grids.forEach(function (grid) {
                        let store = grid.getStore();
                        if (lenthCheck(store.getNewRecords()) || lenthCheck(store.getUpdatedRecords()) || lenthCheck(store.getRemovedRecords())) {
                            panel.mask('Please wait...');
                            gtidIds.push(grid.getId());
                            store.sync({
                                callback: function () {
                                    Ext.Array.remove(gtidIds, grid.getId());
                                    if (gtidIds.length == 0) {
                                        panel.unmask();
                                        Ext.Msg.alert('Info', 'All grid store sync success.');
                                    }
                                }
                            }, grid);
                        }
                    });
                }
            }],
            renderTo: Ext.getBody(),
        })
    }
});
Narendra Jadhav
  • 10,052
  • 15
  • 33
  • 44
  • Thank you for answering. but it's not what i looking for , because i need do something after all `grid.store.sync()` – Hossein Sep 16 '18 at 05:13
  • Yes it's same you can manage after all `store.sync`. I think go through with fiddle and debug the code. Because inside of callback I have checked condition that if all `store.sync` response has came then we can put our logic whatever we want. – Narendra Jadhav Sep 16 '18 at 05:37
  • True. thank you but I think `Promise` is better idea. No? – Hossein Sep 16 '18 at 05:43