反向角度重复


227

我怎样才能得到一个角度反向阵列?我正在尝试使用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>


@QuiteNothing如果要使用表达式反转数组,这是正确的方法。在这种情况下,问题是如何在没有阵列的情况下显示阵列。
JayQuerie.com 2014年

<tr ng-repeat =“朋友中的朋友| orderBy:'-name'”>
desmati

请参阅以下我的答案,以获取简单的1行和正确的解决方案。无需采取任何方法。我不知道为什么人们为此增加了其他方法。
穆罕默德·哈萨姆

始终使用过滤器更改ng-repeat行为!@Trevor Senior做得很好。
阿米尔萨凡德

Answers:


329

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

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

然后可以这样使用:

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

看到它在这里工作:柱塞演示


该过滤器可以根据需要定制,以适应您的需求。我在演示中提供了其他示例。一些选项包括在执行反向操作之前检查变量是否为数组,或者使它更宽松以允许反向处理更多内容,例如字符串。


21
真好!请注意,它items.reverse()会修改数组,而不仅仅是创建一个新数组并返回它。
Anders Ekdahl 2013年

12
谢谢!我忽略了这一点。我提出了slice()解决该问题的方法。
JayQuerie.com 2013年

9
if (!angular.isArray(items)) return false;在尝试反转阵列之前,您应该添加以确认您具有阵列。
respectTheCode

6
需要更加防御null,应改用以下内容:return items?items.slice()。reverse():[];
克里斯·杨

5
@Chris Yeung:建议不要在为null时返回空的“ []”。最好返回原始值。
西瓦2014年

202

这就是我用的:

<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


乌宁(Uing)track by,这是对我

@delboud,您应该在下单后使用跟踪依据:ng-repeat="friend in friends | orderBy:'+': true track by $index"
Vibhum Bhardwaj

125

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

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

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

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

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


1
谢谢你的提示!与其他任何人一样,在rc4(v1.3.0-rc.4)中似乎不起作用。如果有人有机会在新版本中尝试它,请告诉我们!
mikermcneil 2014年

1
@mikermcneil感谢您的评论!根据同一文档,它应该从v1.3.0-rc.5rc.5 docs vs rc.4 docs)开始工作。我已经更新了答案
Dmitry Gonchar 2014年

1
不适用于我(v1.3.5)。试过orderBy:'+':trueorderBy:'-':trueorderBy:'-':falseorderBy:'+':false:(
科迪

2
@Cody对不起,您的回答很晚。在这里,您将找到一个有角度的v1.3.5 jsfiddle.net/dmitry_gonchar/L98foxhm/1的工作示例。问题可能出在另一个地方。
德米特里·贡查

1
@alevkon是的。但是,如果您指定字段('+ id','-id'fe),则该方法有效。也许这是Angular中的一个错误,如果您不指定字段,它就不能按正常顺序工作吗?我从文档中采用了这种方法(答案中有链接),所以我也和您一样感到惊讶。无论如何,问题是如何反转数组。
德米特里·贡查

54

您可以通过$ index参数反转

<tr ng-repeat="friend in friends | orderBy:'$index':true">

13
应该可以,但是不能(尝试使用和不使用引号$index)。我正在使用Angular 1.1.5。
工程师

2
工作对我来说(使用一个属性进行排序,而不是$指数虽然) stackoverflow.com/questions/16261348/...
数码证书

4
不适用于AngularJS 1.2.13。我修改了对象数组,为每个对象添加了一个ID。id是对象在数组内部的索引。然后ng-repeat="friend in friends | orderBy:'id':true"工作。
tanguy_k 2014年


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.reverseArray.prototype.reverse修改原始数组,因此会创建数组的副本。



11

如果您使用的是1.4.4和更高版本的 angularjs ,排序的一种简单方法是使用“ $ 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

您也可以使用.reverse()。这是本机数组函数

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


您的不赞成票只能说明一件事:您有更多传入数据。如果{}或[]继续接收数据,显然每次都会反转。这是一个新的摘要
Pian0_M4n 2015年

警告任何想使用此方法的人:reverse将数组反转就位,它不仅会返回反转的副本。这意味着每次对其求值时,数组将被反转。
jcaron '16

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"}] 


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;
};
}

0

我自己对此问题感到沮丧,因此我修改了@Trevor Senior创建的过滤器,因为我的控制台遇到问题,说它不能使用反向方法。我也想保持对象的完整性,因为这是Angular最初在ng-repeat指令中使用的。在这种情况下,我使用了愚蠢的(key)输入,因为控制台会不高兴地说有重复项,在我的情况下,我需要按$ 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">


0

我添加了一个没人提到的答案。如果有的话,我会尝试让服务器来做。如果服务器返回大量记录,则客户端筛选可能很危险。因为您可能被迫添加分页。如果您从服务器进行分页,则客户端过滤器将按顺序显示在当前页面中。这会使最终用户感到困惑。因此,如果您有服务器,则通过调用发送orderby,然后让服务器将其返回。


0

有用的提示:

您可以使用香草Js反转数组:yourarray .reverse()

注意:反向具有破坏性,因此它将更改您的数组,而不仅是变量。


-2

我建议使用数组本机反向方法总是比创建过滤器或使用更好的选择$index

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

Plnkr_demo


您正在反转原始数组...更好的做法是返回一个反转的新数组。
Vandervidi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.