Why is angular orderBy custom comparator not working?

I am trying to implement a custom comparator for the orderwy angular directive. As you can see in the code snippet, the custom comparator is ignored (nothing is written from console.log), although it should work according to the angular documentation for orderBy

angular.module('orderByExample', [])
.controller('ExampleController', ['$scope', function($scope) {
  $scope.files = [
    {name: 'File1', size: '1.2 Mb'},
    {name: 'File2', size: '2.4 Kb'},
    {name: 'File3', size: '241 Bytes'},
    {name: 'File4', size: '2.0 Mb'},
    {name: 'File5', size: '16.1 Kb'}
  ];

  $scope.fileSizeComparator = function(s1, s2) {
    // split the size string in nummeric and alphabetic parts
    console.log(s1);
    console.log(s2);
    var s1Splitted = s1.size.split(" ");
    var s2Splitted = s2.size.split(" ");
    if (s1Splitted[1] === s2Splitted[1]) {
      // if size type is the same, compare the number
      return s1Splitted[0] > s2Splitted[0];
    }
    // default : compare on size type Mb > Kb > Bytes
    return s1Splitted[1] > s2Splitted[1];
  };
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="orderByExample">
  <div ng-controller="ExampleController">
    <table>
      <tr>
        <th>Name</th>
        <th>Size</th>
      </tr>
      <tr ng-repeat="file in files | orderBy:'size':false:fileSizeComparator">
        <td>{{file.name}}</td>
        <td>{{file.size}}</td>
      </tr>
    </table>
  </div>
</div>
Run codeHide result

I checked the sample code from the angular documentation on JsFiddle and it does not work either. Any ideas?

+4
source share
3 answers

@morels: , 1 -1. , . -, , angular 1.5.7 . .split .value s1 s2.

:

angular.module('orderByExample', [])
.controller('ExampleController', ['$scope', function($scope) {
  $scope.files = [
    {name: 'File1', size: '1.2 Mb'},
    {name: 'File2', size: '2.4 Kb'},
    {name: 'File3', size: '241 Bytes'},
    {name: 'File4', size: '2.0 Mb'},
    {name: 'File5', size: '16.1 Kb'}
  ];

  $scope.fileSizeComparator = function(s1, s2) {
    // split the size string in nummeric and alphabetic parts
    var s1Splitted = s1.value.split(" ");
    var s2Splitted = s2.value.split(" ");
    if (s1Splitted[1] === s2Splitted[1]) {
      // if size type is the same, compare the number
      return parseFloat(s1Splitted[0]) > parseFloat(s2Splitted[0]) ? -1 : 1;
    }
    // default : compare on size type Mb > Kb > Bytes
    return s1Splitted[1] > s2Splitted[1] ? -1 : 1;
  };
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<div ng-app="orderByExample">
  <div ng-controller="ExampleController">
    <table>
      <tr>
        <th>Name</th>
        <th>Size</th>
      </tr>
      <tr ng-repeat="file in files | orderBy:'size':false:fileSizeComparator">
        <td>{{file.name}}</td>
        <td>{{file.size}}</td>
      </tr>
    </table>
  </div>
</div>
Hide result
+10

-1,0,1 true,false.

:

$scope.localeSensitiveComparator = function(v1, v2) {
// If we don't get strings, just compare by index
if (v1.type !== 'string' || v2.type !== 'string') {
  return (v1.index < v2.index) ? -1 : 1;
}

// Compare strings alphabetically, taking locale into account
return v1.value.localeCompare(v2.value);   };

, :

$scope.fileSizeComparator = function(s1, s2) {
    // split the size string in nummeric and alphabetic parts
    console.log(s1);
    console.log(s2);
    var s1Splitted = s1.size.split(" ");
    var s2Splitted = s2.size.split(" ");
    if (s1Splitted[1] === s2Splitted[1]) {
      // if size type is the same, compare the number
      if ( s1Splitted[0] > s2Splitted[0])
        return 1;
      else 
       return -1;
    }
    // default : compare on size type Mb > Kb > Bytes
    return s1Splitted[1] > s2Splitted[1] ? -1 : 1;
  };

, , .. 0.

+1

ng-repeat="file in files | orderBy: sizeFilter: true"

$scope.sizeFilter=function(file){
        $scope.size = file.size;
        return $scope.size;
};
-2

All Articles