我有一组显示特定数字的图块,具体取决于用户选择的选项。我现在想通过显示的任何数字来实现排序。
下面的代码显示了我是如何实现它的(通过获取/设置父卡范围中的值)。现在,因为orderBy函数接受一个字符串,我试图在名为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];
}
}]);
答案 0 :(得分:187)
实际上orderBy
过滤器不仅可以将字符串作为参数,还可以作为函数。来自orderBy
文档:https://docs.angularjs.org/api/ng/filter/orderBy):
功能:Getter功能。此功能的结果将被排序 使用&lt;,=,&gt;操作
所以,你可以编写自己的函数。例如,如果您想根据您在控制器中写入的opt1和opt2(我正在进行此操作,重点是您可以拥有任意函数)来比较卡片:
$scope.myValueFunction = function(card) {
return card.values.opt1 + card.values.opt2;
};
然后,在您的模板中:
ng-repeat="card in cards | orderBy:myValueFunction"
另一件值得注意的事情是,orderBy
只是AngularJS filters的一个示例,因此如果您需要非常具体的排序行为,您可以编写自己的过滤器(尽管orderBy
应该足够对于大多数用例)。
答案 1 :(得分:26)
接受的解决方案仅适用于数组,但不适用于对象或关联数组。不幸的是,由于Angular依赖于数组枚举的JavaScript实现,因此无法一致地控制对象属性的顺序。有些浏览器可能会按字典顺序迭代对象属性,但这不能保证。
e.g。鉴于以下任务:
$scope.cards = {
"card2": {
values: {
opt1: 9,
opt2: 12
}
},
"card1": {
values: {
opt1: 9,
opt2: 11
}
}
};
和指令<ul ng-repeat="(key, card) in cards | orderBy:myValueFunction">
,ng-repeat可以在“card2”之前迭代“card1”,无论排序顺序如何。
要解决此问题,我们可以创建自定义过滤器以将对象转换为数组,然后在返回集合之前应用自定义排序函数。
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
答案 2 :(得分:7)
以下链接非常好地解释了Angular中的过滤器。它显示了如何在ng-repeat中定义自定义排序逻辑。 http://toddmotto.com/everything-about-custom-filters-in-angular-js
对于具有属性的对象排序,这是我使用的代码: (请注意,此类型是标准JavaScript排序方法,并非特定于angular)Column Name是要对其执行排序的属性的名称。
self.myArray.sort(function(itemA, itemB) {
if (self.sortOrder === "ASC") {
return itemA[columnName] > itemB[columnName];
} else {
return itemA[columnName] < itemB[columnName];
}
});
答案 3 :(得分:0)
将方向与orderBy函数一起包括:
ng-repeat="card in cards | orderBy:myOrderbyFunction():defaultSortDirection"
其中
defaultSortDirection = 0; // 0 = Ascending, 1 = Descending