自定义的重复排序函数(Custom sort function in ng-repeat)

2019-06-17 19:25发布

我有一组显示根据哪个选项由用户选择的特定数目的瓦片。 我现在想实现一个排序无论是显示号码。

下面的代码显示了我如何实现它(通过流汗/设置父卡范围的值)。 现在,因为排序依据功能需要一个字符串,我试图设置在名为curOptionValue和排序由该卡范围的变量,但它似乎并没有工作。

于是问题就来了,如何创建自定义排序功能?

<div ng-controller="aggViewport" >
<div class="btn-group" >
    <button ng-click="setOption(opt.name)" ng-repeat="opt in optList" class="btn active">{{opt.name}}</button>
</div>
<div id="container" iso-grid width="500px" height="500px">
    <div ng-repeat="card in cards" class="item {{card.class}}" ng-controller="aggCardController">
        <table width="100%">
            <tr>
                <td align="center">
                    <h4>{{card.name}}</h4>
                </td>
            </tr>
            <tr>
                <td align="center"><h2>{{getOption()}}</h2></td>
            </tr>
        </table>        
    </div>
</div>

和控制器:

module.controller('aggViewport',['$scope','$location',function($scope,$location) {
    $scope.cards = [
        {name: card1, values: {opt1: 9, opt2: 10}},
        {name: card1, values: {opt1: 9, opt2: 10}}
    ];

    $scope.option = "opt1";

    $scope.setOption = function(val){
        $scope.option = val;
    }

}]);

module.controller('aggCardController',['$scope',function($scope){
    $scope.getOption = function(){
        return $scope.card.values[$scope.option];
    }
}]);

Answer 1:

其实orderBy过滤器可以作为参数不仅是一个字符串,但也是一个函数。 从orderBy的文件: https://docs.angularjs.org/api/ng/filter/orderBy ):

功能:吸气功能。 此函数的结果将使用<,=,>运算符进行排序。

所以,你可以写自己的功能。 例如,如果您想根据OPT1和OPT2的总和来比较卡(我做这件事,问题是,你可以有任意的功能),你会在你的控制器写:

$scope.myValueFunction = function(card) {
   return card.values.opt1 + card.values.opt2;
};

然后,在您的模板:

ng-repeat="card in cards | orderBy:myValueFunction"

这里是工作的jsfiddle

值得注意的另外一点是, orderBy仅仅是一个示例AngularJS的过滤器 ,所以如果你需要一个非常具体的订货行为,你可以写自己的过滤器(虽然orderBy应该足以满足大多数使用情况下)。



Answer 2:

接受的解决方案仅适用于阵列,而不是对象或关联数组。 不幸的是,由于角依赖于JavaScript实现阵列枚举的,对象属性的顺序不能始终如一地控制。 一些浏览器可以通过对象的属性迭代字典顺序,但这并不能得到保证。

例如,鉴于以下任务:

$scope.cards = {
  "card2": {
    values: {
      opt1: 9,
      opt2: 12
    }
  },
  "card1": {
    values: {
      opt1: 9,
      opt2: 11
    }
  }
};

和指令<ul ng-repeat="(key, card) in cards | orderBy:myValueFunction"> ,NG-重复可以遍历“卡1”之前,“卡2”,而不管排序顺序的。

要解决这个问题,我们可以创建自定义过滤器将对象转换为一个数组,然后返回集合前应用自定义排序功能。

myApp.filter('orderByValue', function () {
  // custom value function for sorting
  function myValueFunction(card) {
    return card.values.opt1 + card.values.opt2;
  }

  return function (obj) {
    var array = [];
    Object.keys(obj).forEach(function (key) {
      // inject key into each object so we can refer to it from the template
      obj[key].name = key;
      array.push(obj[key]);
    });
    // apply a custom sorting function
    array.sort(function (a, b) {
      return myValueFunction(b) - myValueFunction(a);
    });
    return array;
  };
});

我们不能遍历与自定义过滤器(因为数组键是数字索引)相结合(键,值)配对,这样的模板应更新为引用注入的键名。

<ul ng-repeat="card in cards | orderByValue">
    <li>{{card.name}} {{value(card)}}</li>
</ul>

下面是一个使用的关联数组自定义过滤器工作小提琴: http://jsfiddle.net/av1mLpqx/1/

参考: https://github.com/angular/angular.js/issues/1286#issuecomment-22193332



Answer 3:

通过下面的链接在角介绍过滤器非常好。 它显示了它是如何可能到NG-重复中定义自定义排序逻辑。 http://toddmotto.com/everything-about-custom-filters-in-angular-js

对于具有属性进行排序对象,这是我使用的代码:(请注意,此排序是标准JavaScript排序方法和不特定于有角度的)列名是其上排序是要被执行的属性的名称。

self.myArray.sort(function(itemA, itemB) {
    if (self.sortOrder === "ASC") {
        return itemA[columnName] > itemB[columnName];
    } else {
        return itemA[columnName] < itemB[columnName];
    }
});


Answer 4:

以包括与排序依据功能沿方向:

ng-repeat="card in cards | orderBy:myOrderbyFunction():defaultSortDirection"

哪里

defaultSortDirection = 0; // 0 = Ascending, 1 = Descending


文章来源: Custom sort function in ng-repeat