it-roy-ru.com

angular ng-повторить в обратном порядке

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

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

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

Который затем может быть использован как:

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

Смотрите это работает здесь: Демонстрация Плункер


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

323
querie.cc

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

<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

193
amit bakle

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

Это упоминается в docs : «Если свойство не предоставлено (например,« + »), то сам элемент массива используется для сравнения места сортировки». Итак, решение будет:

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

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

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

122
Dmitry Gonchar

Вы можете повернуть по параметру $ index

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

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

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

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

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

17
Anders Ekdahl

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

13
Kumar

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

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

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

9
vishnu

При использовании MVC в .NET с Angular вы всегда можете использовать OrderByDecending () при выполнении вашего запроса БД следующим образом:

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

Тогда на угловой стороне, это будет уже полностью изменено в некоторых браузерах (IE). При поддержке Chrome и FF вам нужно будет добавить orderBy:

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

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

1
whyoz

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

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

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

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

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

Например,

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

Фильтр orderBy выполняет стабильную сортировку с Angular 1.4.5. (См. Запрос на загрузку GitHub https://github.com/angular/angular.js/pull/12408 .)

Поэтому достаточно использовать предикат constant и значение reverse, равное true:

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

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

0
Jens Alenius

Я сам разочаровался в этой проблеме и поэтому изменил фильтр, созданный @Trevor Senior, когда столкнулся с проблемой с моей консолью, сказав, что она не может использовать обратный метод. Я также хотел сохранить целостность объекта, потому что именно это Angular изначально использует в директиве ng-repeat. В этом случае я использовал ввод stupid (ключ), потому что консоль будет расстроена, говоря, что есть дубликаты, и в моем случае мне нужно было отслеживать по $ 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
Coded Container

Полезный совет:

Вы можете перевернуть массив с помощью Vanilla Js: yourarray .reverse ()

Внимание: реверс является разрушительным, поэтому он изменит ваш массив, а не только переменную.

0
Ke Vin

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

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

0
Pian0_M4n