javascript EXTJS 5:如何在 EXT JS 5 中对网格列进行排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25198722/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
EXTJS 5 : How to sort grid column in EXT JS 5
提问by Micka?l P
I recently updated version of EXT JS to 5 and and override of doSort function no longer works. Someone an idea how to do ?
我最近将 EXT JS 的版本更新为 5,并且 doSort 函数的覆盖不再有效。有人有想法怎么办?
Exampple of override :
覆盖示例:
{
text: 'Custom',
sortable : true,
dataIndex: 'customsort',
doSort: function(state) {
var ds = this.up('grid').getStore();
var field = this.getSortParam();
ds.sort({
property: field,
direction: state,
sorterFn: function(v1, v2){
v1 = v1.get(field);
v2 = v2.get(field);
return v1.length > v2.length ? 1 : (v1.length < v2.length ? -1 : 0);
}
});
}
}
Edit 1 :I just try the solution of @tomgranerod but the me.sortState is always 'undefined'. So I do this to update my variable :
编辑 1:我只是尝试@tomgranerod 的解决方案,但 me.sortState 总是“未定义”。所以我这样做是为了更新我的变量:
sort: function () {
var me = this,
grid = me.up('tablepanel'),
store = grid.store;
me.sortState = me.sortState === 'ASC' ? 'DESC' : 'ASC';
Ext.suspendLayouts();
me.sorting = true;
store.sort({
property: me.getSortParam(),
direction: me.sortState,
sortFn: function (v1, v2) {
v1 = v1.get(field);
v2 = v2.get(field);
return v1.length > v2.length ? 1 : (v1.length < v2.length ? -1 : 0);
}
});
delete me.sorting;
Ext.resumeLayouts(true);
}
But the sortFn funcion is never called. I don't know why. ===> !!!! it works with EXT JS 5.0.1 but the sortFin function is always never called. !!!!
但是 sortFn 函数从未被调用。我不知道为什么。===> !!!!!! 它适用于 EXT JS 5.0.1,但始终不会调用 sortFin 函数。!!!
Edit 2 :This is what i attempt to have :
编辑 2:这就是我想要的:
ASC :
升序:
if (v1 and v2 are numbers) return v1 > v2;
else if (v1 is a number and v2 a string) return false;
else if (v1 is a string and v2 a number) return true;
else if (v1 and v2 are strings) return v1 > v2;
DESC :
描述:
if (v1 and v2 are numbers) return v1 < v2;
else if (v1 is a number and v2 a string) return true;
else if (v1 is a string and v2 a number) return false;
else if (v1 and v2 are strings) return v1 < v2;
采纳答案by Juan Mendes
You were overriding a private method. So it's almost expected that it would break after a major release. If you look at http://docs.sencha.com/extjs/5.0.0/apidocs/source/Column2.html#Ext-grid-column-ColumnYou'll see that there's no doSort
function anymore.
您正在覆盖私有方法。因此,几乎可以预期它会在主要版本后中断。如果您查看http://docs.sencha.com/extjs/5.0.0/apidocs/source/Column2.html#Ext-grid-column-Column您会看到没有任何doSort
功能了。
Ext's suggested way is by to use sortType
configcan take a function which converts your value into something that sorts naturally, usually the easiest thing is to convert it into a number. So if you want something slightly different, you can modify the code I've posted to do what you want without overriding private methods.
Ext 的建议方法是使用sortType
configcan take a function 将您的值转换为自然排序的值,通常最简单的方法是将其转换为数字。因此,如果您想要一些稍微不同的东西,您可以修改我发布的代码以执行您想要的操作,而无需覆盖私有方法。
Running Example: https://fiddle.sencha.com/#fiddle/8km
运行示例:https: //fiddle.sencha.com/#fiddle/8km
var store = Ext.create('Ext.data.Store', {
fields: [{
name: 'ref',
sortType: function(str) {
// Ext-JS requires that you return a naturally sortable value
// not your typical comparator function.
// The following code puts all valid integers in the range
// Number.MIN_SAFE_INTEGER and 0
// And assumes the other values start with T and sorts
// them as positive integers
var parsed = parseInt(str, 10);
if ( isNaN( parsed ) ){
return parseInt(str.substring(1), 10);
} else {
return Number.MIN_SAFE_INTEGER + parsed;
}
}
}],
data: {
'items': [
{'ref': '1'},
{'ref': '12'},
{'ref': 'T0134'},
{'ref': '121878'},
{'ref': 'T0134343'},
{'ref': 'T01POPI'},
{'ref': '103'},
{'ref': 'T01'}
]
},
proxy: {
type: 'memory',
reader: {
type: 'json',
rootProperty: 'items'
}
}
});
Ext.create('Ext.grid.Panel', {
title: 'Grid custom',
store: store,
columns: [{
text: 'Reference',
dataIndex: 'ref',
}],
height: 300,
width: 400,
renderTo: Ext.getBody()
});
If you're going to be reusing this functionality, take a look at http://spin.atomicobject.com/2012/07/20/simple-natural-sorting-in-extjs/
如果您打算重用此功能,请查看http://spin.atomicobject.com/2012/07/20/simple-natural-sorting-in-extjs/
/** Sort on string length */
Ext.apply(Ext.data.SortTypes, {
myCrazySorter: function (str) {
// Same as above
}
});
// And use it like
var store = Ext.create('Ext.data.Store', {
fields: [{
name: 'ref',
sortType: 'myCrazySorter'
}],
回答by tomgranerod
The equivalent function to doSort in ExtJS 5, seem to be 'sort', after a quick look at the source code of Ext.grid.column.Column. The sortState parameter that I've used in this example seem to have been introduced in ExtJS 5.0.1.
在快速查看 Ext.grid.column.Column 的源代码后,ExtJS 5 中 doSort 的等效函数似乎是“排序”。我在这个例子中使用的 sortState 参数似乎是在 ExtJS 5.0.1 中引入的。
sort: function () {
var me = this,
grid = me.up('tablepanel'),
direction,
store = grid.store;
direction = me.sortState === 'ASC' ? 'DESC' : 'ASC';
Ext.suspendLayouts();
me.sorting = true;
store.sort({
sorterFn: function (v1, v2) {
v1 = v1.get(me.getSortParam());
v2 = v2.get(me.getSortParam());
return v1.length > v2.length ? 1 : (v1.length < v2.length ? -1 : 0);
},
direction: direction
});
delete me.sorting;
Ext.resumeLayouts(true);
}
However the solution Juan Mendes describe is a much safer and viable solution than overriding the internal sort function.
然而,Juan Mendes 描述的解决方案比覆盖内部排序功能更安全和可行。
回答by Micka?l P
I finally find a way to compare two records during the sort :
我终于找到了一种在排序过程中比较两条记录的方法:
1) Define a custom Column :
1)定义一个自定义列:
Ext.define('Eloi.grid.column.ReferenceColumn', {
extend : 'Ext.grid.column.Column',
alias : 'widget.referencecolumn',
config : {
ascSorter : null,
descSorter : null
},
destroy : function() {
delete this.ascSorter;
delete this.descSorter;
this.callParent();
},
/**
* @param {String} state The direction of the sort, `ASC` or `DESC`
*/
sort : function(state) {
var me = this,
tablePanel = me.up('tablepanel'),
store = tablePanel.store,
sorter = this[state === 'ASC' ? 'getAscSorter' : 'getDescSorter']();
Ext.suspendLayouts();
this.sorting = true;
store.sort(sorter, state, 'replace');
delete this.sorting;
Ext.resumeLayouts(true);
},
getAscSorter : function() {
var sorter = this.ascSorter;
if (!sorter) {
sorter = new Ext.util.Sorter({
sorterFn : this.createSorter('ASC'),
direction : 'ASC'
});
this.setAscSorter(sorter);
}
return sorter;
},
getDescSorter : function() {
var sorter = this.ascSorter;
if (!sorter) {
sorter = new Ext.util.Sorter({
sorterFn : this.createSorter('DESC'),
direction : 'DESC'
});
this.setAscSorter(sorter);
}
return sorter;
},
createSorter : function(state) {
var dataIndex = this.dataIndex;
return function(rec1, rec2) {
var v1 = rec1.get(dataIndex),
v2 = rec2.get(dataIndex),
num1 = parseInt(v1),
num2 = parseInt(v2),
ret;
if (num1 && num2) {
ret = num1 > num2 ? 1 : (num1 < num2 ? -1 : 0);
} else {
if (!num1 && !num2) {
num1 = parseInt(v1.substr(1));
num2 = parseInt(v2.substr(1));
ret = num1 > num2 ? 1 : (num1 < num2 ? -1 : 0);
}
if (!num1) {
ret = 1;
}
if (!num2) {
ret = -1;
}
}
if (state === 'DESC') {
ret = ret * -1;
}
return ret;
};
}
});
2) set the new type to the column in your grid (with alias) and don't forget to set properly the requires config :
2)将新类型设置为网格中的列(带别名),不要忘记正确设置 requires config :
columns : [
{
xtype : 'referencecolumn',
text : 'Reference',
dataIndex : 'ref',
flex : 1
}
]
回答by Grey2k
You need to use
你需要使用
sorterFn not sortFn
sorterFn 不是 sortFn