AngularJS:如何对多维对象使用orderBy实现ng-repeat按rank排序?
AngularJS ng-repeat 按对象的rank字段排序解决方案
嘿,我来帮你搞定这个排序问题!你当前代码里的orderBy: cars[key].rank写法是有问题的——AngularJS的orderBy过滤器天生更适配数组,而你的cars是键值对结构的对象,而且orderBy的参数上下文也不是你这样用cars[key].rank来访问的。
最直观的解决方案:把对象转换成数组
最简单可靠的方式是在控制器里把对象转成数组,这样orderBy就能正常工作了:
修正后的完整代码:
<div ng-app="myApp" ng-controller="orderCtrl"> <ul> <!-- 遍历转换后的数组,直接按rank排序 --> <li ng-repeat="car in carList | orderBy:'rank' "> {{car.longName}} </li> </ul> </div> <script> var app = angular.module('myApp', []); app.controller('orderCtrl', function($scope) { $scope.cars = { "BTC" : { "longName" : "Bitcoin", "rank" : 1 }, "BCH" : { "longName" : "Bitcoin Cash", "rank" : 3 }, "ETH" : { "longName" : "Ethereum", "rank" : 2 }, "ETC" : { "longName" : "Ethereum Classic", "rank" : 15 }, "IOTA" : { "longName" : "IOTA", "rank" : 4 }, "XRP" : { "longName" : "Ripple", "rank" : 6 }, "XVG" : { "longName" : "Verge", "rank" : 5 } }; // 把对象转换成值数组,这样就能用orderBy正常排序了 $scope.carList = Object.values($scope.cars); }); </script>
额外说明:
- 如果你需要降序排序,只需要把
orderBy:'rank'改成orderBy:'-rank'即可。 - 如果不想修改控制器,也可以自定义一个过滤器把对象转成数组,然后在模板里链式调用:
模板里这样使用:app.filter('toArray', function() { return function(obj) { return Object.values(obj); }; });<li ng-repeat="(key, value) in cars | toArray | orderBy:'rank' "> {{value.longName}} </li>
为什么原代码不行?
原写法里的orderBy: cars[key].rank存在两个核心问题:
- AngularJS对对象的
ng-repeat遍历,默认是按键的字母顺序处理,orderBy过滤器对对象的支持有限,远不如数组稳定。 orderBy的参数应该是针对当前遍历项的属性名或函数,而不是用外部的cars[key]去访问——当遍历对象时,orderBy的上下文是每个value,即便想针对对象排序,也得先把对象转成数组,否则排序逻辑不会生效。
内容的提问来源于stack exchange,提问作者Mka24
相关产品推荐
相关产品推荐

