dates not properly sorted in Angular.js

2019-02-12 13:55发布

问题:

I am relatively new to Angular.js and am having a problem with date sorting. I have looked around the web for similar issues, but haven't found any that are of quite the same flavor.

The situation is as follows:

I am getting a data set back from the database (that I would like to display in a column-header sortable table), in which each record contains a date formatted as a string:

data = [
  {
    "name": "Test_1_Test",
    "creation_date": "8/2/2013 10:31:02 AM"
  },
  {
    "name": "Test_2_Test",
    "creation_date": "8/1/2013 9:12:32 AM"
  },
  {
    "name": "Test_3_Test",
    "creation_date": "9/13/2013 4:55:09 AM"
  }
]

Additionally, I am getting back a set of column headers:

headers = [
  {
    "column": "name",
    "label": "Doc Name"
  },
  {
    "column": "creation_date",
    "label": "Create Date",
    "displayFormat": {
      "dateType": "medium"
    }
  }
]

Using an ng-repeat directive to create the column headers (no trouble there):

<th ng-repeat="column in smartviewColumns">
  <a href="" ng-click="sortBy($index)">
    {{column.label}}
  </a>
</th>

where the sortBy function in the controller is as follows:

$scope.sortBy = function(index){
  if ($scope.sortColumn && $scope.sortColumn === $scope.columns[index]) {
    $scope.reverse = !$scope.reverse;
  }
  $scope.sortColumn = $scope.columns[index];
}

Additionally, using nested ng-repeat directives to create the data rows (across each column) in the table:

<tr ng-repeat="record in data | orderBy:sortColumn:reverse">
  <td ng-repeat="column in headers">
    <div ng-if="column.displayFormat && column.displayFormat.dateType">
      {{getDate(record[column]) | date:column.displayFormat.dateType}}
    </div>
    <div ng-if="!smartviewColumns[$index].displayFormat">
      {{record[smartviewColAttrs[$index]]}}
    </div>    
  </td>
</tr>

The issue is that the dates do not sort properly. When I reverse the order, the list flips but the mis-ordering persists. I have tried formatting the date string differently, as well as calling new Date(creation_date), both to no avail.

Fiddle showing similar symptom

Has anyone else experienced this issue? (Additionally, i should mention that i am using a paginator as a secondary filter on the data rows, but even when excluding it the behavior persists)

回答1:

be aware that it will compare string. It won't compare Dates. You will have to deal with Dates object.

Here is a talk about this.

Here is the solution from vojtajina

Here is part of the solution:

Main.prototype = {

    sort: function(item) {
        if (this.predicate == 'date') {
            return new Date(item.date);
        }
        return item[this.predicate];
    },

    sortBy: function(field) {
        if (this.predicate != field) {
            this.predicate = field;
            this.reverse = false;
        } else {
            this.reverse = !this.reverse;
        }
    },

    reverse: false
};


回答2:

If you want to just order Ascending or Descending, simply

<tr ng-repeat="record in data | orderBy:record.creation_date">
    <td>{{record.name}}</td>
</tr>


回答3:

just you need to always keep your date in similar format.

change

data = [
  {
    "name": "Test_1_Test",
    "creation_date": "08/02/2013 10:31:02 AM"
  },
  {
    "name": "Test_2_Test",
    "creation_date": "08/01/2013 9:12:32 AM"
  },
  {
    "name": "Test_3_Test",
    "creation_date": "09/13/2013 4:55:09 AM"
  }
]

Check fiddle updated

http://jsfiddle.net/HrGdt/28/