Javascript ExtJS 4网格自定义列排序(文件管理器样式)
我正要用extjs4制作一个基本的文件管理器。我现在面临的问题是:如何在单击列时对其进行自定义排序 假设我们有存储字段:Javascript ExtJS 4网格自定义列排序(文件管理器样式),javascript,extjs,extjs4,Javascript,Extjs,Extjs4,我正要用extjs4制作一个基本的文件管理器。我现在面临的问题是:如何在单击列时对其进行自定义排序 假设我们有存储字段: [ { name: "is_dir", type: "boolean" }, { name: "name", type: "string" }, { name: "size", type: "int" } ] 以及来自阵列的数据: [ { is_dir: true, name: "..", size: 0
[
{ name: "is_dir", type: "boolean" },
{ name: "name", type: "string" },
{ name: "size", type: "int" }
]
以及来自阵列的数据:
[
{ is_dir: true, name: "..", size: 0 },
{ is_dir: false, name: "file2.txt", size: 512 },
{ is_dir: true, name: "folder2", size: 0 },
{ is_dir: false, name: "file3.txt", size: 1024 },
{ is_dir: true, name: "folder1", size: 0 },
{ is_dir: true, name: "file1.txt", size: 1024 },
// ...
]
其思想是使排序与任何文件管理器(例如,等)中的排序一样,以便:
- 名为“.”的项目始终放在顶部
- 目录按排序顺序在“.”(如果存在)之后
- 文件按排序顺序跟随目录(如果存在)
^ Name | Size Name | ^ Size
----------------------- -------------------------
.. | 0 .. | 0
folder1 | 0 folder1 | 0
folder2 | 0 folder2 | 0
file1.txt | 1024 file2.txt | 512
file2.txt | 512 file1.txt | 1024
file3.txt | 1024 file3.txt | 1024
我曾尝试为store
sorters
属性编写自定义的sorterFn
,但没有帮助。我相信应该有一些简单的解决方案。您可以覆盖您商店的排序方法:
Ext.define('My.store.FileStore', {
extend: 'Ext.data.Store',
sort: function () {
this.doSort(function() {
// Custom sorting function
console.log(arguments);
return Math.random() > 0.5 ? 1 : -1; // :)
});
}
});
更新
Ext.define('FileModel', {
extend: 'Ext.data.Model',
fields: [
{ name: "is_dir", type: "boolean" },
{ name: "name", type: "string" },
{ name: "size", type: "int" }
]
});
Ext.define('FileStore', {
extend: 'Ext.data.Store',
model: 'FileModel',
data: [
{ is_dir: true, name: "..", size: 0 },
{ is_dir: false, name: "file2.txt", size: 512 },
{ is_dir: true, name: "folder2", size: 0 },
{ is_dir: false, name: "file3.txt", size: 1024 },
{ is_dir: true, name: "folder1", size: 0 },
{ is_dir: false, name: "file1.txt", size: 1024 },
],
sorters: [{
property: 'name',
direction: 'ASC'
}],
sort: function(params) {
var dir = params ? params.direction : 'ASC';
var prop = params ? params.property : 'name';
this.callParent(arguments); // UPDATE 2
this.doSort(function(rec1, rec2) {
var rec1sort = '';
var rec2sort = '';
if (rec1.get('is_dir') && rec2.get('is_dir')) {
// both dirs
if (rec1.get('name') == '..') {
return -1;
}
else if (rec2.get('name') == '..') {
return 1;
}
else {
return rec1.get('name').localeCompare(rec2.get('name')) * (dir == 'ASC' ? 1 : -1);;
}
}
else if (rec1.get('is_dir') != rec2.get('is_dir')) {
// file and dir
if (rec1.get('is_dir')) {
if (rec1.get('name') == '..') {
return -2;
}
else {
return -1;
}
}
else {
if (rec2.get('name') == '..') {
return 2;
}
else {
return 1;
}
}
}
else if (!rec1.get('is_dir') && !rec2.get('is_dir')) {
// both files
var result;
if (typeof rec1.get(prop) == 'number') {
result = rec1.get(prop) - rec2.get(prop);
if (result == 0) {
result = rec1.get('name').localeCompare(rec2.get('name'));
}
}
else {
result = rec1.get('name').localeCompare(rec2.get('name'));
}
return dir == 'ASC' ? result : result * -1;
}
});
}
});
var grid = Ext.create('Ext.grid.Panel', {
title: 'Files',
store: Ext.create('FileStore'),
renderTo: Ext.getBody(),
columns: [{
header: 'Name',
dataIndex: 'name'
}, {
header: 'Size',
dataIndex: 'size'
}]
});
我已经研究了短排序算法。此外,我还修复了双重排序的问题(因为this.callParent(arguments);
从父方法运行基本排序)。以下是一个非常适合我的解决方案:
sort: function(sorters) {
sorters = sorters || { property: "name", direction: "ASC" };
var mod = sorters.direction.toUpperCase() === "DESC" ? -1 : 1;
this.sorters.clear(); // these lines are needed
this.sorters.add(sorters); // to update the column state
this.doSort(function(a, b) {
var a_type = a.get("is_dir"),
b_type = b.get("is_dir"),
a_name = a.get("name"),
b_name = b.get("name");
if (a_name === "..") return -1;
if (a_type === b_type) {
var a_prop = a.get(sorters.property),
b_prop = b.get(sorters.property);
if (a_prop === b_name) {
return (a_name < b_name ? -1 : 1) * mod;
} else {
return (a_prop < b_prop ? -1 : 1) * mod;
}
} else {
return b_type - a_type;
}
});
}
分拣:功能(分拣机){
分拣机=分拣机| |{属性:“名称”,方向:“ASC”};
var mod=sorter.direction.toUpperCase()==“DESC”?-1:1;
this.sorter.clear();//需要这些行
this.sorter.add(sorter);//更新列状态
这个.doSort(函数(a,b){
var a_type=a.get(“is_dir”),
b_type=b.get(“is_dir”),
a_name=a.get(“name”),
b_name=b.get(“name”);
如果(a_name==“.”),返回-1;
如果(a_类型===b_类型){
var a_prop=a.get(sorter.property),
b_prop=b.get(sorter.property);
如果(a_prop==b_name){
返回(a_名称
演示:Sencha的Ext.Store现在包含一个名为
例如:
存储配置:
groupField: 'type', // here you can setup a the attribute of the model to group them by
groupDir: 'DESC' // this is the direction
模型配置:
{
name: 'createdByName',
sortType: 'asUCText',
},
只需这样做并将sortType添加到Models配置中,您现在就可以对按类型分组的列名进行不区分大小写的排序了,但是sorterFn
属性的sorterFn
的作用几乎相同,不是吗?如果是这样,如何使用它考虑到某一列?几乎相同<代码>分拣机
在装载仓库时应用。但当你点击一列时,分拣机不会切冰。似乎工作正常:。谢谢但是,如果多次单击“大小”列,排序方向图像(三角形)会因某种原因消失。但对于“名称”列,它工作得非常好。你知道怎么修吗?找到了this.callParent
是必需的:)+100000。浪费了半天时间试图找到一种方法来更改列的默认排序属性。数据索引是“customKey”,但排序应该是“display”。呃。谢谢你做了这个演示…用我自己独特的数据很容易就可以试用了。我看不到'b_name'@BogdanM的声明。非常正确,我错过了上面的内容。现在修复并更新了演示。