Angular ng-repeat в обратном порядке

Как я могу получить обратный массив в angular? Я пытаюсь использовать фильтр 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>

Ответ 1

Я бы предложил использовать настраиваемый фильтр, например:

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

Что можно затем использовать как:

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

Посмотрите, как он работает здесь: демонстрация плунжера


Этот фильтр можно настроить так, чтобы он соответствовал вашим потребностям. Я привел другие примеры в демонстрации. Некоторые параметры включают проверку того, что переменная представляет собой массив перед выполнением обратного, или сделать его более мягким, чтобы разрешить изменение большего количества вещей, таких как строки.

Ответ 2

Это то, что я использовал:

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

Update:

Мой ответ был в порядке для старой версии Angular. Теперь вы должны использовать

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

или

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

из fooobar.com/questions/31934/...

Ответ 3

Извините за то, что вы это сделали через год, но есть новое, более простое решение, которое работает для Angular v1.3.0-rc.5 и более поздних.

В docs указано: "Если свойство не предоставлено (например," + "), то сам элемент массива используется для сравнения, где сортировка". Таким образом, решение будет:

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

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

Это решение кажется лучше, потому что не модифицирует массив и не требует дополнительных вычислительных ресурсов (по крайней мере, в нашем коде). Я прочитал все существующие ответы и по-прежнему предпочитаю их для них.

Ответ 4

Вы можете изменить параметр $index

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

Ответ 5

Простое решение: - (не нужно делать какие-либо методы)

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

Ответ 6

Вы можете просто вызвать метод в своей области, чтобы отменить его для вас, например:

<!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 изменяет исходный массив.

Ответ 7

если вы используете 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

Ответ 8

Если вы используете angularjs версии 1.4.4 и выше, простой способ сортировки использует " $index".

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

посмотреть демо

Ответ 9

При использовании MVC в .NET с Angular вы всегда можете использовать OrderByDecending() при выполнении своего db-запроса, например:

var reversedList = dbContext.GetAll().OrderByDecending(x => x.Id).ToList();

Затем на стороне Angular в некоторых браузерах (IE) он будет отменен. При поддержке Chrome и FF вам необходимо добавить orderBy:

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

В этом примере вы будете сортировать в порядке убывания свойства .Id. Если вы используете пейджинг, это становится более сложным, потому что будет отсортирована только первая страница. Вам нужно будет обработать это через файл фильтра .js для вашего контроллера или каким-либо другим способом.

Ответ 10

Вы также можете использовать .reverse(). Это встроенная функция массива

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

Ответ 11

Это потому, что вы используете JSON Object. Когда вы сталкиваетесь с такими проблемами, измените объект JSON на объект массива JSON.

Например,

{"India":"IN","America":"US","United Kingdon":"UK"} json object
[{"country":"India","countryId":"IN"},{"country":"America","countryId":"US"},{"country":"United Kingdon","countryId":"UK"}] 

Ответ 13

Я нашел что-то вроде этого, но вместо массива я использую объекты.

Вот мое решение для объектов:

Добавить пользовательский фильтр:

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

Если вам нужна поддержка старого браузера, вам нужно будет определить функцию сокращения (это доступно только в 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;
};
}

Ответ 14

Я сам расстроился из-за этой проблемы, поэтому я изменил фильтр, созданный @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">

Ответ 15

Я добавляю один ответ, о котором никто не упоминал. Я постараюсь сделать сервер, если он у вас есть. Фильтрация клиентов может быть опасной, если сервер возвращает много записей. Потому что вы можете добавить пейджинг. Если у вас есть пейджинг с сервера, тогда клиентский фильтр по заказу будет находиться на текущей странице. Это путало бы конечного пользователя. Поэтому, если у вас есть сервер, отправьте заказ с вызовом и позвольте серверу вернуть его.

Ответ 16

Я бы зарекомендовал себя, используя встроенный обратный метод, всегда лучший выбор по созданию фильтра или с помощью $index.

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

Plnkr_demo.