具有本地排序的缓冲存储(客户端)

Posted

技术标签:

【中文标题】具有本地排序的缓冲存储(客户端)【英文标题】:buffered store with local sorting (client-side) 【发布时间】:2012-06-14 16:36:46 【问题描述】:

我有一个缓冲网格,在该网格上实现了本地排序功能(客户端)。我想在商店重新加载时删除列标题上的排序指示(较暗的背景和小箭头)。

有谁知道如何在 4.1 中实现这一点?

为了更清楚地说明:

希望我的列是可排序的。我不希望他们在禁用排序的情况下进行初始化。用户应该能够单击标题并对其进行排序。 但是,我想要的是能够以编程方式关闭排序。即,删除从用户点击中应用的任何排序类(例如较暗的背景和小排序方向箭头)。

我这样做的原因是因为我使用的是修改后的缓冲存储,它允许我对所有缓冲数据(不仅仅是显示的块)进行本地排序(客户端)。通常,使用缓冲存储会禁用本地排序,因为它只会对显示在网格中的数据进行排序 - 而不是内存中的所有数据,所以 Sencha 的人让任何具有缓冲存储的网格自动禁用本地排序- 只有远程分拣有效。好吧,正如我所说,我的已被修改,因此它可以工作 - 但是当这个缓冲存储重新加载数据库中的新数据时,它不喜欢方便的sortOnLoad 功能,正常网格理所当然地得到。在我的用例中,删除排序状态比覆盖 sortOnLoading 功能并使其对新数据应用相同的排序更合乎逻辑,因此,这个问题。

我现在已经解决了,我会尽快发布一个答案以及我实现的带有 local 排序的缓冲存储,以防有人感兴趣并供我自己将来参考。

我还应该指出,我非常清楚在需要缓冲的存储上进行本地排序(而不是仅对服务器上的数据使用远程排序)带来的客户端性能损失。 I am aware that this is probably why Sencha does not support local sorting on their buffered stores。我已经评估了这方面的所有利弊,在我的特定用例中,这对我来说是最明智的做法。

【问题讨论】:

【参考方案1】:

在 dom 的深处,Ext.grid.header.Container 类和 Ext.grid.column.Column 类上有一个 setSortState 函数。这些不会出现在 4.1.0 文档的任何地方,但它们仍然存在于代码中。

您可以自己查看这些函数以全面了解它们的作用,但它们的要点是一个 switch 语句,它在第一个查找 'DESC''ASC'null论据,例如:

setSortState(`DESC`);
setSortState(`ASC`);
setSortState(null);

使用单个 null 参数调用此函数的标题版本或列版本将删除列上的排序类。唯一真正的区别是标题版本查看网格的存储以在存储的sorters 属性中找到活动的排序器,然后使用该数据来确定在哪一列上调用此函数 - 列版本只是运行列对象它是从哪里调用的。

在我的用例中,我没有向 store sorters 属性添加排序器,因此我使用的是列版本(即从 Ext.grid.column.Column 对象调用 setSortState)。

首先,这是我实现的允许本地(客户端)排序的缓冲存储的示例:

Ext.define('MyApp.store.TheBufferedStoreWithLocalSorting', 
    extend: 'Ext.data.Store',
    requires: [
        'Ext.ux.data.PagingMemoryProxy',
        'Ext.util.MixedCollection'
    ],
    model: 'MyApp.model.SomeModel',
    buffered: true,
    pageSize: 100,
    remoteSort: true, // this just keeps sorting from being disabled
    proxy: 
        type: 'pagingmemory',
        reader: 'json'
    ,
    /* 
     * Custom sort function that overrides the normal store sort function.
     * Basically this pulls all the buffered data into a MixedCollection
     * and applies the sort to that, then it puts the SORTED data back
     * into the buffered store.               
     */                    
    sort: function(sorters) 
        var collection = new Ext.util.MixedCollection();

        collection.addAll(this.proxy.data);
        collection.sort(sorters);
        this.pageMap.clear();
        this.getProxy().data = collection.getRange();
        this.load();

    
);

现在,为了回答我的问题,每当商店重新加载时删除排序器类,我只需要这样做:

Ext.each(myGrid.columns, function(column, index) 
    if (column.hasCls('x-column-header-sort-ASC') ||
        column.hasCls('x-column-header-sort-DESC')) 
        myGrid.columns[index].setSortState(null);
        return false;
    
);

【讨论】:

【参考方案2】:

当商店重新加载时,您可以将以下内容添加到商店的加载事件处理程序中:

Ext.create("Ext.data.Store", 

    listeners: 
        load: 
            fn: function () 
                grid.addCls("no-sort-icon");
            
        
    
;

然后修改您的 css 以在元素是“no-sort-icon”的子元素时隐藏图标(这将在网格上)

.no-sort-icon .x-column-header-text 
    background-image: none;

.no-sort-icon .x-column-header 
    background-color: #C5C5C5;

【讨论】:

【参考方案3】:

如果我理解正确,在指定列上设置此配置应该可以解决您的问题

columns: [
    text: 'First Name',  dataIndex:'firstname', sortable: false,
    text: 'Last Name',  dataIndex:'lastname',
 ]

更多详情在这里http://docs.sencha.com/ext-js/4-0/#!/api/Ext.grid.column.Column-cfg-sortable

这是一个配置选项,因此它会在第一次呈现网格时禁用列的可排序性。

这是jsfiddle demo

* 请注意,我使用分机。 4.0.7,你可以切换到4.1.0,但是由于某种原因弹出了一个与下拉列表无关的显示错误

【讨论】:

意识到,虽然这种方法禁用了对特定列的排序,但它不会从标题中隐藏排序箭头图像 我澄清了我的澄清 :) 另外,我现在已经解决了,我稍后会发布我的答案。 感谢您的明确澄清 :),那我完全错了。期待你的回答

以上是关于具有本地排序的缓冲存储(客户端)的主要内容,如果未能解决你的问题,请参考以下文章

具有本地存储的会话

PHP MongoDB 驱动程序的游标如何缓冲结果集?

备份具有完整历史记录的SVN存储库

ExtJs 4.1.0 缓冲网格 + 本地排序/过滤

在 ASP.NET Core 中上传文件

PostgreSQL本地化