Angular中的ng-repeat如何倒序显示?

231

我该如何在Angular中获取一个反转的数组? 我尝试使用orderBy过滤器,但它需要一个谓词(例如'name')来排序:

<tr ng-repeat="friend in friends | orderBy:'name':true">
      <td>{{friend.name}}</td>
      <td>{{friend.phone}}</td>
      <td>{{friend.age}}</td>
<tr>

有没有一种方法可以在不排序的情况下反转原始数组,就像这样:

<tr ng-repeat="friend in friends | orderBy:'':true">
      <td>{{friend.name}}</td>
      <td>{{friend.phone}}</td>
      <td>{{friend.age}}</td>
<tr>

4
这是新的正确方法。https://dev59.com/qGQo5IYBdhLWcg3wKsxr#16261373 - om471987
@QuiteNothing 如果你想用一个表达式来反转一个数组,那么这就是正确的方法。但在这种情况下,问题是如何在没有表达式的情况下反转一个数组。 - Jay
<tr ng-repeat="friend in friends | orderBy:'-name'"> - Hossein
请看下面我的答案,这是简单而正确的解决方案。没有必要再创建其他方法了。我想知道为什么有人还要创建额外的方法。 - Muhammad Hassam
在更改ng-repeat行为时,始终使用过滤器! @Trevor Senior干得很好。 - Amir Savand
17个回答

333

我建议使用自定义过滤器,例如:

app.filter('reverse', function() {
  return function(items) {
    return items.slice().reverse();
  };
});

然后可以像这样使用:

<div ng-repeat="friend in friends | reverse">{{friend.name}}</div>

在这里可以看到它的运行效果:Plunker演示


此过滤器可以根据您的需要进行自定义,如演示中所示。提供了其他示例以供参考。一些选项包括在执行反转之前检查变量是否为数组,或使其更加宽松以允许反转更多的内容,例如字符串。


21
好的!请注意items.reverse()修改了数组本身,而不是只创建一个新的并返回它。 - Anders Ekdahl
12
谢谢!我之前忽略了这一点。为了解决这个问题,我添加了slice() - Jay
9
在尝试反转数组之前,您应该添加if (!angular.isArray(items)) return false;以验证您是否拥有一个数组。 - respectTheCode
6
需要更加防御空值,应该使用以下代码替代:return items ? items.slice().reverse() : []; - Chris Yeung
5
不建议在值为 null 时返回空的 "[]",最好返回原始值。 - Siva
显示剩余4条评论

208

这是我使用的:

<alert ng-repeat="alert in alerts.slice().reverse()" type="alert.type" close="alerts.splice(index, 1)">{{$index + 1}}: {{alert.msg}}</alert>

更新:

我的回答适用于旧版本的Angular。现在,你应该使用

ng-repeat="friend in friends | orderBy:'-'"

或者

ng-repeat="friend in friends | orderBy:'+':true"

源自 https://dev59.com/1GUp5IYBdhLWcg3wdXWa#26635708


使用 track by,这是我唯一行之有效的方法。 - user240993
@delboud,你应该在orderBy之后使用track by: ng-repeat="friend in friends | orderBy:'+': true track by $index" - Vibhum Bhardwaj
这对我实际起作用了。非常感谢。 - Nayana Chandran

124
抱歉一年后才提出这个问题,但是有一个新的、更简单的解决方案,适用于Angular v1.3.0-rc.5及以上版本。在docs中提到:“如果没有提供属性(例如'+'),则使用数组元素本身进行比较排序”。所以解决方案将是: ng-repeat="friend in friends | orderBy:'-'" 或者 ng-repeat="friend in friends | orderBy:'+':true"。这个解决方案似乎更好,因为它不修改数组,也不需要额外的计算资源(至少在我们的代码中是如此)。我已经阅读了所有现有的答案,仍然更喜欢这个答案。

1
谢谢你的提示!提醒一下其他读者,看起来这在rc4 (v1.3.0-rc.4)中不起作用。如果有人有机会尝试新版本,请告诉我们! - mikermcneil
1
@mikermcneil,感谢您的评论!根据相同的文档,它应该从 v1.3.0-rc.5 开始工作(rc.5 docs 相对于 rc.4 docs)。 我已经更新了答案。 - Dmitry Gonchar
1
对我不起作用(v1.3.5)。尝试过 orderBy:'+':trueorderBy:'-':trueorderBy:'-':falseorderBy:'+':false :( - Cody
2
@Cody 抱歉回复晚了。这是一个使用angular v1.3.5的工作示例 https://jsfiddle.net/dmitry_gonchar/L98foxhm/1/。可能问题出在其他地方。 - Dmitry Gonchar
1
@alevkon 确实如此。但是如果您指定字段(例如'+id','-id'),它就可以正常工作。也许这是Angular的一个错误,如果您不指定字段,它就无法按照正常顺序工作?我从文档中获取了这种方法(链接在答案中),所以我和您一样感到惊讶。无论如何,问题是如何反转数组。 - Dmitry Gonchar
显示剩余4条评论

57

简单的解决方案:-(无需创建任何方法)

ng-repeat = "friend in friends | orderBy: reverse:true"

2
对我来说完全正常。谢谢! - HankScorpio

55
你可以通过$index参数进行反转。
<tr ng-repeat="friend in friends | orderBy:'$index':true">

13
应该可以工作,但实际上并没有(无论是否在$index周围添加引号都尝试过)。我使用的是Angular 1.1.5版本。 - Engineer
2
对我有用(不过我们使用的是排序属性而不是$index) https://dev59.com/qGQo5IYBdhLWcg3wKsxr - Certs
4
不支持AngularJS 1.2.13。我修改了我的对象数组,为每个对象添加了一个ID,该ID是该对象在数组中的索引。然后使用ng-repeat="friend in friends | orderBy:'id':true"就可以工作了。 - tanguy_k

17
你可以在作用域上调用一个方法来反转它,像这样:

<!doctype html>
<html ng-app="myApp">
<head>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://code.angularjs.org/1.0.5/angular.min.js"></script>
    <script>
    angular.module('myApp', []).controller('Ctrl', function($scope) {
        $scope.items = [1, 2, 3, 4];
        $scope.reverse = function(array) {
            var copy = [].concat(array);
            return copy.reverse();
        }
    });
    </script>
</head>
<body ng-controller="Ctrl">
    <ul>
        <li ng-repeat="item in items">{{item}}</li>
    </ul>
    <ul>
        <li ng-repeat="item in reverse(items)">{{item}}</li>
    </ul>
</body>
</html>

请注意,$scope.reverse会创建数组的一个副本,因为Array.prototype.reverse会修改原始数组。

13

如果您正在使用1.3.x版本,则可以使用以下内容:

{{ orderBy_expression | orderBy : expression : reverse}}

示例按照出版日期降序列出图书

<div ng-repeat="book in books|orderBy:'publishedDate':true">

source:https://docs.angularjs.org/api/ng/filter/orderBy


11

如果您正在使用 angularjs 版本1.4.4 及以上,一种简单的排序方法是使用 "$index"。

 <ul>
  <li ng-repeat="friend in friends|orderBy:$index:true">{{friend.name}}</li>
</ul>

查看演示


1
在使用.NET和Angular的MVC时,您可以始终在执行数据库查询时使用OrderByDecending(),如下所示:
var reversedList = dbContext.GetAll().OrderByDecending(x => x.Id).ToList();

然后在Angular方面,在某些浏览器(IE)中,它已经被反转了。当支持Chrome和FF时,您需要添加orderBy:

<tr ng-repeat="item in items | orderBy:'-Id'">

在这个例子中,您会按照 .Id 属性的降序进行排序。如果您正在使用分页,则会变得更加复杂,因为只有第一页会被排序。您需要通过控制器的 .js 过滤文件或其他方式来处理这个问题。

0

orderBy 过滤器在 Angular 1.4.5 中执行 稳定排序。(请参见 GitHub pull request https://github.com/angular/angular.js/pull/12408。)

因此,只需使用一个 常量 谓词和设置为 truereverse 即可:

<div ng-repeat="friend in friends | orderBy:0:true">{{friend.name}}</div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接