Javascript 底部有空格的日期的自定义排序函数
Javascript custom sort function for dates with blanks at the bottom
我正在使用 table 插件 (ng-grid) 来显示一堆数据,其中包括一些日期列。该插件允许使用 "sortingAlgorithm" 函数进行自定义排序,该函数接受 "aDate" 和 "bDate" 参数。日期在数据库中存储为字符串,我使用 Moment 将它们转换为日期对象。这是排序函数:
sortingAlgorithm: function (aDate, bDate) {
var a = moment(aDate, 'MM/DD/YYYY');
var b = moment(bDate, 'MM/DD/YYYY');
if (a.isBefore(b)) {
return -1;
}
else if (a.isAfter(b)) {
return 1;
}
else {
return 0;
}
}
这工作正常,但如果没有日期,只是一个空字符串,当按升序排序时,空格会出现在列表的末尾,但当按降序排序时,空格会出现在列表的开头。如何确保空格 ("") 始终移至列表底部?
谢谢。
更新
我认为这与 UI-Grid 库有关。参见 rowSorter.js。它似乎在内部处理空值,这正在破坏我的魔力。我也看不到选择的排序方向在哪里公开供我使用...
我正在添加 "angular-ui-grid" 标签...
如果ng-grid插件使用排序算法,然后应用reverse()
降序排序,那么我认为你不能强制将项目放在最后。我猜你将不得不覆盖插件中的排序。
为了测试空字符串,你可以把你的比较条件放在前面,所以 ''
总是在最后。这样您就不会通过强制 moment.js 解析空字符串来创建无效日期。
sortingAlgorithm: function(aDate, bDate) {
if (aDate === '') {
return 1;
}
if (bDate === '') {
return -1;
}
var a = moment(aDate, 'MM/DD/YYYY');
var b = moment(bDate, 'MM/DD/YYYY');
if (a.isBefore(b)) {
return -1;
} else if (a.isAfter(b)) {
return 1;
} else {
return 0;
}
}
试试这个:
var direction=1;
var sortingAlgorithm= function (aDate, bDate) {
var a=moment(aDate,'MM/DD/YYYY');
var b=moment(bDate,'MM/DD/YYYY');
if (!a.isValid()) return 1;
if (!b.isValid()) return -1;
return direction*((+a)-(+b));
}
它考虑了日期和方向的有效性(1或-1),所以无效的日期总是在底部。
所以我复制了一份 ui-grid 的内部日期特定排序函数,并将它们的 "handleNulls" 函数调用替换为我自己的(见下文):
sortingAlgorithm: function (a, b) {
var nulls = handleNulls(a, b);
if ( nulls !== null ){
return nulls;
} else {
if (!(a instanceof Date)) {
a = new Date(a);
}
if (!(b instanceof Date)){
b = new Date(b);
}
var timeA = a.getTime(),
timeB = b.getTime();
return timeA === timeB ? 0 : (timeA < timeB ? -1 : 1);
}
}
这里是 ui-grid 的 "handleNulls" 函数的副本,已更新为始终根据方向将空值强制到底部:
function handleNulls(a, b) {
if ((!a && a !== 0 && a !== false) || (!b && b !== 0 && b !== false)) {
if ((!a && a !== 0 && a !== false) && (!b && b !== 0 && b !== false)) {
return 0;
}
else if (!a && a !== 0 && a !== false && vm.direction === 'asc') {
return 1;
}
else if (!b && b !== 0 && b !== false && vm.direction === 'asc') {
return -1;
}
else if (!a && a !== 0 && a !== false && vm.direction === 'desc') {
return -1;
}
else if (!b && b !== 0 && b !== false && vm.direction === 'desc') {
return 1;
}
}
return null;
};
vm.direction 来自 ui-grid 的 onRegisterApi 回调,它有一个用于排序更改的钩子:
onRegisterApi: function (gridApi) {
vm.gridApi = gridApi;
vm.gridApi.core.on.sortChanged($scope, function(grid, sortColumns) {
if (sortColumns[0]) {
vm.direction = sortColumns[0].sort.direction;
} else {
vm.direction = 'none';
}
});
}
很有魅力!
这是我基于这个和另一个使用 moment.js
的线程得出的结论
var sortmedate = function (a, b, rowA, rowB, direction) {
//the dates do not get sorted properly so we need moment.js and this method.
var dateFormat = 'MM/DD/YYYY'; //todo: pass in date format from mvc controller.
if (!a && !b) {
return 0;
}
if (!a) {
return 1;
}
if (!b) {
return -1;
}
var firstDate = moment(a, dateFormat);
if (!firstDate.isValid()) {
return -1;
}
var secondDate = moment(b, dateFormat);
if (!secondDate.isValid()) {
return 1;
}
if (firstDate.isSame(secondDate)) {
return 0;
} else {
return firstDate.isBefore(secondDate) ? -1 : 1;
}
};
我正在使用 table 插件 (ng-grid) 来显示一堆数据,其中包括一些日期列。该插件允许使用 "sortingAlgorithm" 函数进行自定义排序,该函数接受 "aDate" 和 "bDate" 参数。日期在数据库中存储为字符串,我使用 Moment 将它们转换为日期对象。这是排序函数:
sortingAlgorithm: function (aDate, bDate) {
var a = moment(aDate, 'MM/DD/YYYY');
var b = moment(bDate, 'MM/DD/YYYY');
if (a.isBefore(b)) {
return -1;
}
else if (a.isAfter(b)) {
return 1;
}
else {
return 0;
}
}
这工作正常,但如果没有日期,只是一个空字符串,当按升序排序时,空格会出现在列表的末尾,但当按降序排序时,空格会出现在列表的开头。如何确保空格 ("") 始终移至列表底部?
谢谢。
更新
我认为这与 UI-Grid 库有关。参见 rowSorter.js。它似乎在内部处理空值,这正在破坏我的魔力。我也看不到选择的排序方向在哪里公开供我使用...
我正在添加 "angular-ui-grid" 标签...
如果ng-grid插件使用排序算法,然后应用reverse()
降序排序,那么我认为你不能强制将项目放在最后。我猜你将不得不覆盖插件中的排序。
为了测试空字符串,你可以把你的比较条件放在前面,所以 ''
总是在最后。这样您就不会通过强制 moment.js 解析空字符串来创建无效日期。
sortingAlgorithm: function(aDate, bDate) {
if (aDate === '') {
return 1;
}
if (bDate === '') {
return -1;
}
var a = moment(aDate, 'MM/DD/YYYY');
var b = moment(bDate, 'MM/DD/YYYY');
if (a.isBefore(b)) {
return -1;
} else if (a.isAfter(b)) {
return 1;
} else {
return 0;
}
}
试试这个:
var direction=1;
var sortingAlgorithm= function (aDate, bDate) {
var a=moment(aDate,'MM/DD/YYYY');
var b=moment(bDate,'MM/DD/YYYY');
if (!a.isValid()) return 1;
if (!b.isValid()) return -1;
return direction*((+a)-(+b));
}
它考虑了日期和方向的有效性(1或-1),所以无效的日期总是在底部。
所以我复制了一份 ui-grid 的内部日期特定排序函数,并将它们的 "handleNulls" 函数调用替换为我自己的(见下文):
sortingAlgorithm: function (a, b) {
var nulls = handleNulls(a, b);
if ( nulls !== null ){
return nulls;
} else {
if (!(a instanceof Date)) {
a = new Date(a);
}
if (!(b instanceof Date)){
b = new Date(b);
}
var timeA = a.getTime(),
timeB = b.getTime();
return timeA === timeB ? 0 : (timeA < timeB ? -1 : 1);
}
}
这里是 ui-grid 的 "handleNulls" 函数的副本,已更新为始终根据方向将空值强制到底部:
function handleNulls(a, b) {
if ((!a && a !== 0 && a !== false) || (!b && b !== 0 && b !== false)) {
if ((!a && a !== 0 && a !== false) && (!b && b !== 0 && b !== false)) {
return 0;
}
else if (!a && a !== 0 && a !== false && vm.direction === 'asc') {
return 1;
}
else if (!b && b !== 0 && b !== false && vm.direction === 'asc') {
return -1;
}
else if (!a && a !== 0 && a !== false && vm.direction === 'desc') {
return -1;
}
else if (!b && b !== 0 && b !== false && vm.direction === 'desc') {
return 1;
}
}
return null;
};
vm.direction 来自 ui-grid 的 onRegisterApi 回调,它有一个用于排序更改的钩子:
onRegisterApi: function (gridApi) {
vm.gridApi = gridApi;
vm.gridApi.core.on.sortChanged($scope, function(grid, sortColumns) {
if (sortColumns[0]) {
vm.direction = sortColumns[0].sort.direction;
} else {
vm.direction = 'none';
}
});
}
很有魅力!
这是我基于这个和另一个使用 moment.js
的线程得出的结论 var sortmedate = function (a, b, rowA, rowB, direction) {
//the dates do not get sorted properly so we need moment.js and this method.
var dateFormat = 'MM/DD/YYYY'; //todo: pass in date format from mvc controller.
if (!a && !b) {
return 0;
}
if (!a) {
return 1;
}
if (!b) {
return -1;
}
var firstDate = moment(a, dateFormat);
if (!firstDate.isValid()) {
return -1;
}
var secondDate = moment(b, dateFormat);
if (!secondDate.isValid()) {
return 1;
}
if (firstDate.isSame(secondDate)) {
return 0;
} else {
return firstDate.isBefore(secondDate) ? -1 : 1;
}
};