如何使用过滤数据保留 ExtJS 网格中的选择?

Posted

技术标签:

【中文标题】如何使用过滤数据保留 ExtJS 网格中的选择?【英文标题】:How can I preserve the selections in an ExtJS grid with filtered data? 【发布时间】:2014-03-31 16:11:41 【问题描述】:

我正在使用 ExtJS 4.1.2,并且我有一个 Ext.grid.Panel,其中包含一个复选框选择模型和一个用于过滤网格中项目的标题中的文本框:

var nameStore = new Ext.data.Store(
    ...
    proxy:  type: 'ajax' ... ,
    fields: [  name: 'name', type: 'string' , ... ],
);

var headerBar = new Ext.toolbar.Toolbar(
    xtype: 'toolbar',
    dock: 'top',
    layout: 'fit',
    items: [
        xtype: 'textfield',
        ...,
        listeners: 
            change: function(fld, newVal, oldVal, opts) 
                var grid = ...;
                if (newVal.length > 0)
                    grid.store.filterBy(function(record, id)  return record.get('name').indexOf(newVal) !== -1; );
                else
                    grid.store.clearFilter()
            
        
    ]
);

var nameGrid = new Ext.grid.Panel(
    ...
    selType: 'checkboxmodel',
    selModel:  mode: 'SIMPLE' ,
    store: nameStore,
    columns: [  dataIndex: 'name', flex: true , ... ],
    dockedItems: [ headerBar ],
    bbar: [  xtype: 'tbtext', text: '0 items selected' ... ,
    listeners: 
        selectionchange: function(selModel, selected, opts) 
            var txt = ...;
            txt.setText(Ext.String.format("0 items selected", selected.length));
        
    
);

如图所示,nameStore 的过滤器根据headerBar 文本框中的值应用(或删除)。此外,底部栏中的文本字符串会随着项目的选择/取消而更新。

这些功能中的每一个都可以独立运行。但是交互给我带来了麻烦:如果选择了一个项目并且然后被过滤out,它会被取消选择,然后在过滤器被清除时仍然如此。

如何保持对“隐藏”项目的选择(或至少对用户来说是这样做的),以便在我的应用程序的其他地方使用或在清除过滤器时重新选择?谢谢!

【问题讨论】:

您必须在过滤网格之前存储当前选择,以便稍后引用该选择。请问您为什么要尝试保存被过滤掉的项目的选择?我很好奇,因为这个功能对我来说似乎不是很直观。 @forgivenson,总列表有数百个项目,但给定的用户通常一次对大约 10-15 个项目感兴趣。这个想法是使用过滤器来允许用户快速找到他们特别感兴趣的那几个项目并选择它们。然后将所选集合用作应用程序中其他操作的参数。 然后让他们过滤到他们想要的内容,选择那些,然后执行他们将对该选择执行的任何其他操作。让我们看一个例子:我选择了一些项目,然后过滤掉,大多数选择的项目都没有了。我选择了更多,然后按不同的内容进行过滤,再选择一些,等等。用户应该如何跟踪他/她选择的内容?如果你真的想做这样的事情,我会添加一个单独的网格,一个“选定的网格”,它存储每条记录,因为它被选中,并且不会被过滤器的更改清除。 因为过滤器被用作搜索。考虑汽车品牌和型号的列表。用户过滤到那些包含“BMW”的项目,选择那些,然后将过滤器更改为“Audi”并选择那些。文本标签显示所选项目的总数(宝马和奥迪),这些项目被传递给其他操作,但用户不希望包括福特、本田等。 【参考方案1】:

您不需要单独添加选定的网格。这只能在一个网格中完成。简单的方法是在页面范围内设置一个数组变量,然后根据需要捕获网格选择事件或 itemclick 事件。

例如,如果您使用 select 事件,它将为您提供记录。

select( this, record, index, eOpts )

您可以获取您的记录 id 并将其推送到您声明的数组变量中。 一旦你过滤掉了网格。您可以遍历过滤的记录并通过获取选择模型来调用选择方法。 例如

grid.getSelectionModel().select(record);

希望这会有所帮助。

【讨论】:

感谢您的建议,但问题是应用过滤器(调用 filterBy())会触发取消选择事件,然后重新选择先前选择的项目会触发选择事件,这些事件正在管理那个数组变量。所以没有一个好的方法来判断是添加/删除数组变量,还是忽略取消选择/选择事件“因为它们来自过滤器更改”。 你可以有一个 bool 变量来检查这些甚至应该何时触发。例如 var afterfilterselection = true;当您要对每条记录应用选择时,切换此方法以执行事件处理程序的其余部分。 if(!afterfilterselection) afterfilterselection = false;返回; 我最终使用了与您建议的方法类似的方法。谢谢。

以上是关于如何使用过滤数据保留 ExtJS 网格中的选择?的主要内容,如果未能解决你的问题,请参考以下文章

Extjs 如何使网格列标题菜单选项保留在 Cookies 中(有状态)

ExtJS:: 如何过滤网格中的行,但不在存储中

如何在 ExtJS 4 网格面板中保留垂直滚动条?

如何在每个组 ExtJS 4 中过滤分组网格

选项卡内的 EXTJS 网格 - 过滤器仅适用于页面刷新

Extjs-如何用鼠标右键选择网格中的行