230

我怎样才能获得角度的反转数组?我正在尝试使用 orderBy 过滤器,但它需要一个谓词(例如“名称”)来排序:

<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

17 回答 17

333

我建议使用这样的自定义过滤器:

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

然后可以像这样使用:

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

在这里看到它的工作:Plunker Demonstration


该过滤器可以根据您的需要进行定制。我在演示中提供了其他示例。一些选项包括在执行反向操作之前检查变量是否为数组,或者更宽松地允许对更多事物(例如字符串)进行反向操作。

于 2013-03-07T09:42:22.787 回答
206

这是我用的:

<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://stackoverflow.com/a/26635708/1782470

于 2014-04-12T13:23:31.223 回答
124

很抱歉在一年后提出这个问题,但是有一个新的、更简单的解决方案,它适用于 Angular v1.3.0-rc.5 及更高版本

文档中提到:“如果没有提供属性(例如'+'),则数组元素本身用于比较排序位置”。因此,解决方案将是:

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

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

这个解决方案似乎更好,因为它不修改数组并且不需要额外的计算资源(至少在我们的代码中)。我已经阅读了所有现有的答案,并且仍然更喜欢这个答案。

于 2014-10-29T16:26:24.810 回答
57

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

ng-repeat = "friend in friends | orderBy: reverse:true"
于 2016-10-03T09:04:13.813 回答
54

您可以通过 $index 参数反转

<tr ng-repeat="friend in friends | orderBy:'$index':true">
于 2013-09-22T18:01:19.510 回答
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

于 2013-03-07T09:10:58.967 回答
13

如果您使用的是 1.3.x,则可以使用以下内容

{{ orderBy_expression | orderBy : expression : reverse}}

示例按出版日期降序排列书籍

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

来源:https ://docs.angularjs.org/api/ng/filter/orderBy

于 2015-05-07T10:11:40.040 回答
11

如果您使用 angularjs 1.4.4 及更高版本,一个简单的排序方法是使用“ $index ”。

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

查看演示

于 2016-06-02T13:36:24.227 回答
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 过滤器文件或以其他方式处理此问题。

于 2017-02-14T00:42:19.543 回答
0

您也可以使用 .reverse()。这是一个原生数组函数

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

于 2015-08-14T12:31:38.537 回答
0

那是因为您使用的是 JSON 对象。当您遇到此类问题时,请将您的 JSON 对象更改为 JSON 数组对象。

例如,

{"India":"IN","America":"US","United Kingdon":"UK"} json object
[{"country":"India","countryId":"IN"},{"country":"America","countryId":"US"},{"country":"United Kingdon","countryId":"UK"}] 
于 2016-02-06T08:23:12.490 回答
0

从Angular 1.4.5 开始,orderBy过滤器执行稳定的排序。(请参阅 GitHub 拉取请求https://github.com/angular/angular.js/pull/12408。)

因此,使用常量谓词并reverse设置为就足够了true

<div ng-repeat="friend in friends | orderBy:0:true">{{friend.name}}</div>
于 2016-02-14T20:12:28.020 回答
0

我发现了类似的东西,但是我使用对象而不是数组。

这是我的对象解决方案:

添加自定义过滤器:

app.filter('orderObjectBy', function() {
    return function(items, field, reverse){

        var strRef = function (object, reference) {
            function arr_deref(o, ref, i) {
                return !ref ? o : (o[ref.slice(0, i ? -1 : ref.length)]);
            }
            function dot_deref(o, ref) {
                return !ref ? o : ref.split('[').reduce(arr_deref, o);
            }
            return reference.split('.').reduce(dot_deref, object);
        };

        var filtered = [];

        angular.forEach(items, function(item) {
           filtered.push(item);
        });
        filtered.sort(function (a, b) {
           return (strRef(a, field) > strRef(a, field) ? 1 : -1);
        });
        if(reverse) filtered.reverse();
        return filtered;
    };
});

然后可以像这样使用

<div ng-repeat="(key, value) in items | orderObjectBy:'field.any.deep':true">

如果您需要旧的浏览器支持,则需要定义 reduce 函数(仅在 ECMA-262 mozilla.org中可用)

// Production steps of ECMA-262, Edition 5, 15.4.4.21
// Reference: http://es5.github.io/#x15.4.4.21
if (!Array.prototype.reduce) {
Array.prototype.reduce = function(callback /*, initialValue*/) {
'use strict';
  if (this == null) {
    throw new TypeError('Array.prototype.reduce called on null or undefined');
  }
  if (typeof callback !== 'function') {
    throw new TypeError(callback + ' is not a function');
  }
  var t = Object(this), len = t.length >>> 0, k = 0, value;
  if (arguments.length == 2) {
    value = arguments[1];
  } else {
    while (k < len && !(k in t)) {
      k++; 
    }
    if (k >= len) {
      throw new TypeError('Reduce of empty array with no initial value');
    }
    value = t[k++];
  }
  for (; k < len; k++) {
    if (k in t) {
      value = callback(value, t[k], k, t);
    }
  }
  return value;
};
}
于 2016-04-26T14:05:54.970 回答
0

我自己对这个问题感到沮丧,所以我修改了@Trevor Senior 创建的过滤器,因为我的控制台遇到了一个问题,说它不能使用反向方法。我还想保持对象的完整性,因为这是 Angular 最初在 ng-repeat 指令中使用的。在这种情况下,我使用了愚蠢(键)的输入,因为控制台会因为说有重复而感到不安,而在我的情况下,我需要通过 $index 进行跟踪。

筛选:

angular.module('main').filter('reverse', function() {
    return function(stupid, items) {
    var itemss = items.files;
    itemss = itemss.reverse();  
    return items.files = itemss; 
  };
});

HTML: <div ng-repeat="items in items track by $index | reverse: items">

于 2016-08-12T14:49:27.787 回答
0

我添加了一个没有人提到的答案。如果您有服务器,我会尝试让服务器执行此操作。如果服务器返回大量记录,客户端过滤可能会很危险。因为您可能会被迫添加分页。如果您有来自服务器的分页,那么客户端过滤器将在当前页面中。这会使最终用户感到困惑。因此,如果您有服务器,则通过调用发送 orderby 并让服务器返回它。

于 2017-01-17T10:23:47.587 回答
0

有用的提示:

你可以用 vanilla Js 反转你的数组: yourarray .reverse()

注意:反向是破坏性的,所以它会改变你的数组,而不仅仅是变量。

于 2018-11-12T20:37:24.040 回答
-2

我建议使用数组本机反向方法总是比创建过滤器或使用$index.

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

Plnkr_demo .

于 2015-09-14T13:40:13.607 回答