ng-repeat中的自定义sortingfunction

我有一组显示一定数量的图块,具体取决于用户select哪个选项。 现在我想通过显示的任何数字来实现一个sorting。

下面的代码显示了我如何实现它(通过获取/设置父卡范围中的值)。 现在,因为orderBy函数需要一个string,我试图在名为curOptionValue的卡片范围中设置一个variables,然后对其进行sorting,但似乎不起作用。

所以问题就变成了,我如何创build一个自定义的sorting函数?

<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]; } }]); 

其实orderByfilter不仅可以作为一个参数,而且可以作为一个函数。 从orderBy文档: http : orderBy : orderBy ):

函数:Getter函数。 这个函数的结果将使用<,=,>运算符进行sorting。

所以,你可以写自己的function。 例如,如果您想根据opt1和opt2的总和比较卡片(我提出这个问题,重点是您可以有任意的function),您可以在控制器中写入:

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

然后,在您的模板中:

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

这是工作jsFiddle

另外值得注意的是orderBy只是AngularJSfilter的一个例子,所以如果你需要一个非常特定的sorting行为,你可以编写你自己的filter(尽pipeorderBy应该足够用于大多数用例)。

接受的解决scheme只适用于数组,而不适用于对象或关联数组。 不幸的是,由于Angular依赖于数组枚举的JavaScript实现,因此对象属性的顺序不能一致地被控制。 有些浏览器可能按照字典顺序遍历对象属性,但这不能得到保证。

例如给定以下任务:

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

和指令<ul ng-repeat="(key, card) in cards | orderBy:myValueFunction"> ,则无论sorting顺序如何,ng-repeat都可以在“card2”之前迭代“card1”。

要解决这个问题,我们可以创build一个自定义filter来将对象转换为数组,然后在返回集合之前应用自定义的sorting函数。

 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; }; }); 

我们不能迭代(键,值)配对与自定义​​filter(因为数组的键是数字索引),因此模板应该更新以引用注入的键名称。

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

这是一个工作小提琴在联合数组上使用自定义filter: http : //jsfiddle.net/av1mLpqx/1/

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

以下链接非常好地解释了Angular中的filter。 它显示了如何在ng-repeat中定义自定义sorting逻辑。 http://toddmotto.com/everything-about-custom-filters-in-angular-js

对于使用属性sorting对象,这是我使用的代码:(请注意,这种sorting是标准的JavaScriptsorting方法,而不是特定于angular)Column Name是要执行sorting的属性的名称。

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