我试图根据可能需要比较多于1个字段的顺序函数显示值列表,因此标准的单参数函数对我来说是不够的。
我希望带有描述的项目位于列表的顶部(无论描述是什么)以及上半部分(带描述)和下半部分(没有描述)我希望按名称按字母顺序排列
我有这样的事情:
<div ng-repeat="item in items | orderBy:memberSort">
{{item.sortName}} / {{item.description}}
</div>
和比较器:
$scope.memberSort = function(m1, m2) {
if (m1.description && !m2.description) {
return -1;
}
if (m2.description && !m1.description) {
return 1;
}
return m1.sortName.localCompare(m2.sortName);
};
如何使用这样的比较器而不仅仅是单参数值函数?在上面的代码中,参数m2总是未定义的。
这是一个jsfiddle:https://jsfiddle.net/1Lwg4s2r/15/
虽然这只是当前的一个问题,但一般的问题是如何定义一个接受2个值的比较器函数,而不仅仅是一个将复杂对象映射到值的单参数函数?
答案 0 :(得分:3)
由于angularjs 1.5.7,Angularjs OrderBy pipe can take a function as comparator,但我认为使用JavaScript array.sort()绑定一个返回排序数组的函数要简单得多。
HTML
<div ng-repeat="item in getSortedItems()">
{{item.sortName}} / {{item.description}}
</div>
<强> JS 强>
function myCtrl($scope) {
$scope.items = [
{description: 'Boss',sortName: 'Joe'},
//... rest of your items
];
$scope.getSortedItems = function() {
return $scope.items.sort(function(m1, m2) {
if (m1.description && !m2.description)
return -1;
if (m2.description && !m1.description)
return 1;
return m1.sortName.localeCompare(m2.sortName);
});
};
}
如果您关心性能,不要使用angularjs过滤器来执行简单的任务,例如排序数组。在我的解决方案中,sort函数执行两次(如果您可以对数组进行排序然后将值分配给绑定变量会更好),在接受的解决方案中执行20次。
答案 1 :(得分:2)
您必须指定memberSort
比较器作为orderBy
的第三个参数:
angular.module('app', []).controller('myController', function($scope) {
$scope.items = [
{ description: '', sortName: 'Bob' },
{ description: '', sortName: 'Steve' },
{ description: '', sortName: 'Mark' },
{ description: 'Member', sortName: 'Kirk' },
{ description: 'Boss', sortName: 'Joe' }
];
$scope.memberSort = function(o1, o2) {
var m1 = o1.value, m2 = o2.value;
if (m1.description && !m2.description)
return -1;
if (m2.description && !m1.description)
return 1;
return m1.sortName.localeCompare(m2.sortName);
};
});
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<div ng-app='app' ng-controller="myController">
<div ng-repeat="item in items | orderBy: 'valueOf()' : false : memberSort">
{{item.sortName}} / {{item.description}}
</div>
</div>