我有一个ng-repeat迭代一组对象,需要一些函数来提取我想要排序的值.
我的ng-repeat看起来像这样:
ng-repeat="row in rows | orderBy: [sortFnOne,sortFnTwo,...]"
我遇到麻烦的是,我希望sortFnOne被颠倒过来.这些是提取我无法使用简单属性访问的字符串,因为它正在对数据进行一些转换以生成我尝试排序的这些值.
如果它很简单,我知道我会这样做:
ng-repeat="row in rows | orderBy: ['-id','name','-status',...]"
如果这些功能只是返回布尔我可以!获取我想要的结果的返回值,但其中一些是返回字符串,有些是以YYYY-MM-DD格式返回日期.
我自己也遇到过这个限制……没有办法用orderBy过滤器来反转函数完成的排序.
原文链接:https://www.f2er.com/angularjs/141140.html据我所知,没有简单的方法可以在原生JavaScript API中重现这种带方向的复合排序(按’A’升序然后’B’降序排序).
Array.prototype.sort通过比较函数提供基本排序(有关详细信息,请参阅MDN docs),但无法在不编写其他比较函数的情况下轻松切换排序顺序(反向),并且它不提供复合排序的解决方案.我们需要的是一个紧凑的表示法来指定多个排序的方向和优先级.
前段时间我写了这个助手来帮助解决这个问题.
var orderByAgeThenName = new OrderByBuilder().asc(getAge).asc(getName).build(); var friendsByAgeThenName = orderByAgeThenName(friends); var orderByNameThenAge = new OrderByBuilder().desc(getName).asc(getAge).build(); var friendsByNameThenAge = orderByNameThenAge(friends);
这不是角度过滤器,因此只需将其包装在控制器方法中并从模板中调用它即可.或者,只需将顺序应用于控制器内的阵列即可.
我想这可以适应角度过滤器……
可运行样本:
angular.module('orderByExample',[]) .controller('ExampleController',['$scope',function($scope) { var friends = [{name:'Jon',phone:'555-1212',age:10},{name:'Zach',phone:'555-2276',age:7},phone:'555-9876',age:19},phone:'555-9276',age:13},{name:'Mike',phone:'555-4321',age:21},{name:'Adam',phone:'555-5678',age:35},{name:'Julie',phone:'555-8765',age:29}]; function getName(f){ return f.name; } function getAge(f){ return f.age; } var orderByName = new OrderByBuilder().desc(getName).build(); var orderByNameAndAge = new OrderByBuilder().desc(getName).asc(getAge).build(); $scope.friendLists = [ {label:'Not Ordered',friends: friends},{label:'Name DESC',friends: orderByName(friends)},{label:'Name DESC,Age ASC',friends: orderByNameAndAge(friends)} ]; }]); function OrderByBuilder(orderings){ var _orderings = []; return { asc: function(fn){ addOrdering(true,fn); return this; },desc: function(fn){ addOrdering(false,build: build }; function addOrdering(asc,fn){ _orderings.push({ getterFn: fn,asc: asc }); return this; } function build(){ var compare = _orderings.reverse().reduce(function(nextComparer,ordering){ return getComparerFn(ordering,nextComparer); },null); return function(xs){ return xs.slice().sort(compare); }; } // a comparerFn has the following signature: // function(a: obj,b: obj): int function getComparerFn(ordering,nextComparer){ var next = nextComparer || function(a,b){ return 0; }; var getVal = ordering.getterFn; return function(a,b){ var aVal = getVal(a); var bVal = getVal(b); if(aVal < bVal){ return ordering.asc ? -1 : 1; } if(aVal > bVal){ return ordering.asc ? 1 : -1; } return next(a,b); }; } }
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.0-beta.6/angular.min.js"></script> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> <div ng-app="orderByExample"> <div ng-controller="ExampleController"> <div class="row"> <div ng-repeat="friendList in friendLists" class="col-sm-4"> <h4>{{friendList.label}}</h4> <table class="table table-bordered table-condensed"> <tr> <th>Name</th> <th>Phone Number</th> <th>Age</th> </tr> <tr ng-repeat="friend in friendList.friends"> <td>{{friend.name}}</td> <td>{{friend.phone}}</td> <td>{{friend.age}}</td> </tr> </table> </div> </div> </div> </div>