【问题标题】:How to wait until all stores are Sync in ExtJs?如何等到所有商店都在 ExtJs 中同步?
【发布时间】:2019-02-19 23:15:04
【问题描述】:

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

我写了下面的代码:

$.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() 没有等待回调。

推荐的方法是什么?

【问题讨论】:

  • store.sync() 不应该是必需的,首先...使用配置autoSync: true
  • @MartinZeitler 我在网格中有很多数据,不想为每个单元格编辑发送请求。
  • 它只会同步已更改的一行 - 而用户一次不会更改超过一行 - 这几乎不会增加流量,只会分成更多请求。在某些时候,人们往往拥有 > 100mbit/s 的速度,即使在家里也是如此。
  • @MartinZeitler 我用Promise 做,无论如何谢谢。
  • @MartinZeitler autoSync 改变程序的行为。不知道你为什么推荐它。您是否希望 Excel 无需询问即可自动保存所有更改?

标签: javascript extjs promise gridpanel extjs-stores


【解决方案1】:

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

【讨论】:

  • 从这里:sencha.com/forum/…
  • @EvanTrimboli :( 是的。我也在那里问过这个问题
  • 只是一些归属。
【解决方案2】:

您可以将callback 用于您的store.sync() 方法。

同步完成后调用的回调函数。无论成功或失败都会调用回调,并传递以下参数:(batch, options)。

你可以这样实现你的要求

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

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

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

您可以在这里查看工作Fiddle

注意我使用了 dummy 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(),
        })
    }
});

【讨论】:

  • 感谢您的回答。但这不是我要找的,因为我毕竟需要做点什么grid.store.sync()
  • 是的,您毕竟可以管理store.sync。我认为通过小提琴并调试代码。因为在回调内部,我已经检查了条件,如果所有store.sync 响应都来了,那么我们可以把我们的逻辑放在任何我们想要的地方。
  • 是的。谢谢,但我认为Promise 是更好的主意。没有?
猜你喜欢
  • 1970-01-01
  • 2012-02-25
  • 2012-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-05
  • 2017-02-24
相关资源
最近更新 更多