如何等到所有商店在 ExtJs 中同步?

How to wait until all stores are Sync in ExtJs?

我有一个网格列表,可以由最终用户更改表单中的数据。 最后,我想通过点击按钮同步所有的网格,然后执行一个操作。

我写了下面的代码:

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

问题是store.sync()没有等待回调。

推荐的方法是什么?

您可以使用 callback 作为您的 store.sync() 方法。

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

你可以这样实现你的要求

  1. 在循环前取一个空数组名。像这样 var gridIds=[].

  2. store.sync() 将网格 ID 推入上述数组之前的循环侧。

  3. 现在在 callback 函数中从上面的数组中删除该网格 ID 并检查条件数组是否为空,然后您的所有商店同步响应已经到来。

你可以在这里检查工作Fiddle

注意 我使用了虚拟 api。请使用您的实际 api.

代码片段

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

我用 Promise 这样做:

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