web-dev-qa-db-fra.com

ng-repeat angulaire en sens inverse

Comment puis-je obtenir un tableau inversé en mode angulaire? J'essaie d'utiliser le filtre orderBy, mais il nécessite un prédicat (par exemple, 'nom') pour trier:

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

Est-il possible d'inverser le tableau d'origine, sans trier . Comme ça:

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

Je suggérerais d'utiliser un filtre personnalisé comme celui-ci:

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

Ce qui peut alors être utilisé comme:

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

Regardez le travail ici: Démonstration Plunker


Ce filtre peut être personnalisé pour répondre à vos besoins à votre guise. J'ai fourni d'autres exemples dans la démonstration. Certaines options consistent notamment à vérifier que la variable est un tableau avant d’opérer l’inverse, ou à la rendre plus souple pour permettre l’inversion de plusieurs éléments, tels que des chaînes.

323
querie.cc

C'est ce que j'ai utilisé:

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

Mettre à jour:

Ma réponse était OK pour l'ancienne version de Angular. Maintenant, vous devriez utiliser 

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

ou

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

de https://stackoverflow.com/a/26635708/1782470

193
amit bakle

Désolé de le signaler après un an, mais il existe une nouvelle solution, plus facile, qui fonctionne pour Angular v1.3.0-rc.5 et versions ultérieures}. 

Il est mentionné dans docs : "Si aucune propriété n’est fournie, (par exemple, '+'), l’élément de tableau lui-même est utilisé pour comparer le tri". La solution sera donc:

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

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

Cette solution semble être meilleure car elle ne modifie pas un tableau et ne nécessite pas de ressources de calcul supplémentaires (au moins dans notre code). J'ai lu toutes les réponses existantes et je leur préfère encore celle-ci.

122
Dmitry Gonchar

Vous pouvez inverser le paramètre $ index

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

Solution simple: - (pas besoin de faire des méthodes)

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

Vous pouvez simplement appeler une méthode sur votre oscilloscope pour l'inverser, comme ceci:

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

Notez que le $scope.reverse crée une copie du tableau car Array.prototype.reverse modifie le tableau d'origine.

17
Anders Ekdahl

si vous utilisez 1.3.x, vous pouvez utiliser les éléments suivants

{{ orderBy_expression | orderBy : expression : reverse}}

Exemple Liste des livres par date de publication en ordre décroissant

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

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

13
Kumar

Si vous utilisez angularjs version 1.4.4 et ultérieure, un moyen facile de trier est d'utiliser "$ index".

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

voir la démo

9
vishnu

Lorsque vous utilisez MVC dans .NET avec Angular, vous pouvez toujours utiliser OrderByDecending () lorsque vous effectuez votre requête de base de données comme suit:

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

Ensuite, du côté angulaire, il sera déjà inversé dans certains navigateurs (IE). Lorsque vous prenez en charge Chrome et FF, vous devez alors ajouter orderBy:

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

Dans cet exemple, vous triez par ordre décroissant sur la propriété .Id. Si vous utilisez la pagination, cela devient plus compliqué car seule la première page serait triée. Vous devrez gérer cela via un fichier de filtre .js pour votre contrôleur ou d'une autre manière.

1
whyoz

J'ai trouvé quelque chose comme ça, mais au lieu de tableau j'utilise des objets.

Voici ma solution pour les objets:

Ajouter un filtre personnalisé:

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

Qui peut alors être utilisé comme

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

Si vous avez besoin d’un ancien navigateur, vous devrez définir la fonction de réduction (disponible uniquement dans 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

C'est parce que vous utilisez un objet JSON. Lorsque vous rencontrez de tels problèmes, changez ensuite votre objet JSON en objet de tableau JSON.

Par exemple,

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

Le filtre orderBy effectue un tri stable à partir de Angular 1.4.5. (Voir la demande d'extraction GitHub https://github.com/angular/angular.js/pull/12408 .)

Donc, il suffit d'utiliser un prédicat constant et reverse à true:

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

J'ajoute une réponse que personne n'a mentionnée. Je voudrais essayer de faire le serveur si vous en avez un. Le filtrage côté client peut être dangereux si le serveur renvoie beaucoup d'enregistrements. Parce que vous pourriez être obligé d'ajouter la pagination. Si vous effectuez une pagination à partir du serveur, le filtre client sur commande apparaît dans la page en cours. Ce qui dérouterait l'utilisateur final. Donc, si vous avez un serveur, envoyez la commande avec l'appel et laissez le serveur la renvoyer.

0
Jens Alenius

J'étais moi-même frustré par ce problème et j'ai donc modifié le filtre créé par @Trevor Senior, car je rencontrais un problème avec ma console en disant qu'il ne pouvait pas utiliser la méthode inverse. Je souhaitais également conserver l'intégrité de l'objet car c'est ce que Angular utilise à l'origine dans une directive ng-repeat. Dans ce cas, j'ai utilisé l'entrée de stupid (clé) car la console va s'énerver en disant qu'il y a des doublons et que dans mon cas j'avais besoin de suivre par $ index. 

Filtre: 

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

Conseil utile:

Vous pouvez inverser votre tableau avec Vanilla Js: yourarray .reverse ()

Attention: reverse est destructif, donc cela changera votre tableau, pas seulement la variable.

0
Ke Vin