【问题标题】:State provider does not restore sorters properly状态提供者未正确恢复分拣机
【发布时间】:2015-11-30 00:49:10
【问题描述】:

我正在尝试使用 Ext.state.CookieProvider 存储我的网格状态。问题是当状态本身(宽度、顺序)正常恢复时,我无法恢复分拣机参数。

首先我在视口视图控制器的 init() 方法中创建了 cookieprovider:

Ext.state.Manager.setProvider(Ext.create('Ext.state.CookieProvider', {}));

我的商店设置为使用远程排序自动加载:

Ext.define('MyApp.requests.store.QueryRequestsGridStore', {
    extend: 'Ext.data.Store',
    model: 'MyApp.requests.model.QueryRequestsGridModel',
    alias: 'store.queryRequestsGrid',
   remoteSort: true,
    autoLoad: true,
    proxy: {
        startParam: 'offset',
        limitParam: 'limit',
        url: '/requests',
        noCache: false,
        type: 'ajax',
        reader: {
            type: 'json',
            rootProperty: 'data',
            totalProperty: 'total'
        }
    },
});

Store 是使用 viewmodel 绑定在网格中定义的:

bind: {
    store: '{queryRequestsGrid}'
},

我在按钮点击时从视口视图控制器加载包含商店的网格,如下所示:

var panelToAddName = Ext.create('MyApp.requests.view.QueryRequestsGridView', {});
var mainViewPort = Ext.ComponentQuery.query('#mainViewPort')[0];
var regionPanel = mainViewPort.down('[region=center][xtype=panel]');
regionPanel.removeAll();
regionPanel.add(panel);

Cookie 包含排序器,但加载网格时没有任何排序参数。

"storeState":{"sorters":[{"root":"data","property":"date_completed","direction":"ASC"}]}}}

我深入研究了 ext-all-debug.js 源文件,发现了“Ext.state.Stateful”类的 initState() 方法。

initState: function() {
        var me = this,
            id = me.stateful && me.getStateId(),
            hasListeners = me.hasListeners,
            state, combinedState, i, len, plugins, plugin, pluginType;
        if (id) {
            combinedState = Ext.state.Manager.get(id);
            if (combinedState) {
                state = Ext.apply({}, combinedState);
                if (!hasListeners.beforestaterestore || me.fireEvent('beforestaterestore', me, combinedState) !== false) {

                    plugins = me.getPlugins() || [];
                    for (i = 0 , len = plugins.length; i < len; i++) {
                        plugin = plugins[i];
                        if (plugin) {
                            pluginType = plugin.ptype;
                            if (plugin.applyState) {
                                plugin.applyState(state[pluginType], combinedState);
                            }
                            delete state[pluginType];
                        }
                    }

                    me.applyState(state);
                    if (hasListeners.staterestore) {
                        me.fireEvent('staterestore', me, combinedState);
                    }
                }
            }
        }
    },

如果从该方法内部记录 me.store,则存储在控制台中显示为 ext-empty-storeme 是我加载的网格。似乎在正确加载商店之前正在应用状态。

如果在 beforerender 网格事件中重用 initState 方法,排序器将正确地从 cookie 中恢复。

有什么建议吗?

【问题讨论】:

  • 我建议制作一个非常简单的煎茶小提琴(带有单列的网格,加载带有单个字段的商店等),这会出现问题。然后你也把它作为一个错误发布在煎茶论坛上。
  • 我刚刚还注意到一件事:您可以将代码发布到您将商店添加到网格的位置/方式,以及将状态添加到网格的位置/方式。有几种方法可以添加商店(store:'MyStoreId'store:Ext.create('MyApp.store.MyStore'),这可能会表现出不同的行为。
  • @Alexander,我已经添加了你建议的代码,它有帮助吗?如果没有,我会做一个煎茶小提琴。

标签: extjs


【解决方案1】:

我没有使用 viewmodel 绑定作为 store 和 grid 之间的唯一绑定,并且无法评论这是否应该工作,或者只是偶然。

但我知道viewmodel处理得很晚,因为view必须先完全初始化(包括applyState),所以viewmodel可以找到它想要绑定监听器的所有组件。

因此,请尝试使用两种“老式”方法中的任何一种添加商店,即使没有视图模型也可以使用:网格上的store:'MyStoreId'store:Ext.create('MyApp.store.MyStore')。这样,商店应该在applyState 之前绑定到网格。

此外,我看到另一个您应该解决的问题:您的商店在商店初始化后直接加载。 (autoLoad:true)。那时,它还没有绑定到网格;因此,没有应用排序/过滤器,这意味着启用remoteSort/remoteFilter 时,您向服务器发送了太多请求。我建议仅在应用到网格后才加载存储(在 callParent 调用后的 grid.initComponent 中,或从 grid.boxready 侦听器中)。如果您真的想使用autoLoad,我建议您查看setAutoLoad 方法

【讨论】:

  • 感谢您的回答,将 autoLoad 设置为 false 并使用 store:Ext.create('MyApp.store.MyStore', {}) 方法似乎可以解决问题。现在我正在考虑如何以这种方式处理视图模型。
猜你喜欢
  • 2014-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-02
  • 2016-04-16
相关资源
最近更新 更多