AngularJS按对象内数组首元素值orderBy排序报错问题
解决AngularJS中对象内数组的排序问题
首先得揪出你代码里的几个核心问题:
- 你的
$scope.items是对象(包含books和movies两个数组属性),但直接用ng-repeat="item in items"遍历的是对象的键名(books、movies),根本不是数组里的元素; orderBy过滤器只能处理数组,没法直接作用于对象;- 你写的
orderBy:items[0].position完全无效——items是对象,items[0]根本不存在,这就是语法错误的源头。
下面根据两种常见需求场景,给你对应的正确实现方案:
场景1:分别对books和movies数组内部元素按position排序
如果你想分开展示排序后的书籍和电影列表,代码可以这么写:
控制器代码(保留你原有的数据结构)
$scope.items = { books: [ {position: 1}, {title: 'Harry Potter'}, {title: 'Lord of The Rings'} ], movies: [ {position: 0}, {title: 'Mission Impossible'}, {title: 'Star Wars'} ] };
模板代码
<!-- 排序并展示书籍列表 --> <h3>书籍列表(按position排序)</h3> <div class="item" ng-repeat="book in items.books | orderBy:'position'"> {{ book }} </div> <!-- 排序并展示电影列表 --> <h3>电影列表(按position排序)</h3> <div class="item" ng-repeat="movie in items.movies | orderBy:'position'"> {{ movie }} </div>
这里orderBy:'position'会根据数组中每个对象的position属性升序排序,想要降序的话改成orderBy:'-position'就行。
场景2:合并books和movies数组后整体按position排序
如果你想把两个数组合并成一个列表,再按position统一排序展示,可以先在控制器里完成数组合并:
控制器代码
$scope.items = { books: [ {position: 1}, {title: 'Harry Potter'}, {title: 'Lord of The Rings'} ], movies: [ {position: 0}, {title: 'Mission Impossible'}, {title: 'Star Wars'} ] }; // 合并books和movies数组 $scope.allItems = $scope.items.books.concat($scope.items.movies);
模板代码
<h3>合并后的总列表(按position排序)</h3> <div class="item" ng-repeat="item in allItems | orderBy:'position'"> {{ item }} </div>
额外补充:处理无position属性的元素
你的数组里有些元素没有position(比如{title: 'Harry Potter'}),AngularJS会把这类元素的position视为undefined,升序时会排在最前面。如果想把它们放到最后,可以自定义排序函数:
$scope.sortByPosition = function(item) { // 给无position的元素一个极大值,让它们排到最后 return item.position !== undefined ? item.position : Infinity; };
模板里改成:
ng-repeat="item in allItems | orderBy:sortByPosition"
内容的提问来源于stack exchange,提问作者Jordash
相关产品推荐
相关产品推荐

