为什么角顺序自定义比较器不能工作

Why is angular orderBy custom comparator not working?

本文关键字:不能 工作 比较器 自定义 顺序 为什么      更新时间:2023-09-26

我正在尝试为角orderBy指令实现自定义比较器。正如您在代码片段中看到的那样,尽管定制比较器应该根据orderBy

的angular文档工作,但它被忽略了(console.log中没有记录任何内容)。

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>

我在JsFiddle上测试了angular文档中的示例代码,它也不起作用。什么好主意吗?

我在@morels的帮助下找到了解决方案:是的,我确实应该返回1和-1。但主要问题是比较国被忽略了。显然,这是因为这个特性只对angular 1.5.7及更高版本可用。我还需要对传递给s1和s2的参数的.value使用.split

下面是代码片段中的工作解决方案:

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>

因为您应该返回-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

这样做

ng-repeat="file in files | orderBy: sizeFilter: true"
$scope.sizeFilter=function(file){
        $scope.size = file.size;
        return $scope.size;
};