ripetizione angolare al contrario


227

Come posso ottenere un array inverso in angolare? sto cercando di utilizzare il filtro orderBy, ma ha bisogno di un predicato (ad esempio 'nome') per ordinare:

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

C'è un modo per invertire l'array originale, senza ordinare. come quello:

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

4
Questo è il nuovo e giusto modo stackoverflow.com/a/16261373/988830
om471987

@QuiteNothing Questo è il modo giusto se si desidera invertire un array con un'espressione. In questo caso, la domanda era come venerare un array senza uno.
JayQuerie.com,

<tr ng-repeat = "amico negli amici | orderBy: '- name'">
desmati

Vedi la mia risposta di seguito per la semplice riga 1 e la soluzione corretta. Non è necessario effettuare alcun metodo. Mi chiedo perché le persone stiano facendo metodi aggiuntivi per questo.
Muhammad Hassam,

Usa sempre i filtri per modificare il ng-repeatcomportamento! @Trevor Senior ha fatto un buon lavoro.
Amir Savand,

Risposte:


329

Suggerirei di utilizzare un filtro personalizzato come questo:

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

Che può quindi essere usato come:

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

Guardalo funzionare qui: dimostrazione di Plunker


Questo filtro può essere personalizzato per adattarsi alle tue esigenze come meglio si vede. Ho fornito altri esempi nella dimostrazione. Alcune opzioni includono il controllo che la variabile sia un array prima di eseguire il contrario, o renderlo più indulgente per consentire l'inversione di più cose come le stringhe.


21
Bello! Basta essere consapevoli del fatto che items.reverse()modifica l'array invece di crearne uno nuovo e restituirlo.
Anders Ekdahl

12
Grazie! L'avevo trascurato. Ho inserito un a slice()per risolvere quel problema.
JayQuerie.com

9
È necessario aggiungere if (!angular.isArray(items)) return false;per verificare di disporre di un array prima di provare a invertirlo.
rispettare il codice

6
Devi essere più difensivo contro null, utilizzare invece quanto segue: restituire gli articoli? items.slice (). reverse (): [];
Chris Yeung,

5
@Chris Yeung: non consigliabile restituire "[]" vuoto quando null. Meglio restituire il valore originale.
Siva,

202

Questo è quello che ho usato:

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

Aggiornare:

La mia risposta era OK per la vecchia versione di Angular. Ora dovresti usare

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

o

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

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


Uing track by, questo è l'unico modo che ha funzionato per me

@delboud dovresti usare la traccia dopo l'ordineDa:ng-repeat="friend in friends | orderBy:'+': true track by $index"
Vibhum Bhardwaj

125

Ci scusiamo per averlo presentato dopo un anno, ma esiste una nuova soluzione più semplice , che funziona per Angular v1.3.0-rc.5 e successive .

È menzionato nei documenti : "Se non viene fornita alcuna proprietà (ad es. '+'), L'elemento array stesso viene utilizzato per confrontare l'ordinamento". Quindi, la soluzione sarà:

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

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

Questa soluzione sembra essere migliore perché non modifica un array e non richiede risorse di calcolo aggiuntive (almeno nel nostro codice). Ho letto tutte le risposte esistenti e preferisco ancora questa a loro.


1
Grazie per il consiglio! Come testa a testa per chiunque legga questo, sembra che questo non funzioni in rc4 ( v1.3.0-rc.4). Se qualcuno ha la possibilità di provarlo nella nuova versione, faccelo sapere!
mikermcneil,

1
@mikermcneil Grazie per il commento! Secondo la stessa documentazione dovrebbe funzionare a partire da v1.3.0-rc.5( documenti rc.5 vs documenti rc.4 ). Ho aggiornato la risposta
Dmitry Gonchar il

1
Non funziona per me (v1.3.5). Provato orderBy:'+':true, orderBy:'-':true, orderBy:'-':false, orderBy:'+':false:(
Cody

2
@Cody Ci scusiamo per la risposta tardiva. Ecco qui - un esempio funzionante con angolare v1.3.5 jsfiddle.net/dmitry_gonchar/L98foxhm/1 . Probabilmente il problema era in un altro posto.
Dmitry Gonchar,

1
@alevkon True. Funziona se si specifica il campo ('+ id', '-id' fe). Forse questo è un bug in Angolare, che non funziona con l'ordine normale se non si specifica un campo? Ho preso questo metodo dai documenti (il link è nella risposta), quindi sono stato sorpreso come te. Comunque, la domanda era come invertire un array.
Dmitry Gonchar,

54

È possibile invertire il parametro $ index

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

13
Dovrebbe funzionare, ma non funziona (provato con e senza virgolette $index). Sono su Angular 1.1.5.
Ingegnere

2
Ha lavorato per me (sono state utilizzando una proprietà per l'ordinamento invece di $ index però) stackoverflow.com/questions/16261348/...
Certs

4
Non funziona con AngularJS 1.2.13. Ho modificato la mia matrice di oggetti per aggiungere un ID a ciascun oggetto. L'id è l'indice dell'oggetto all'interno dell'array. Quindi ng-repeat="friend in friends | orderBy:'id':true"funziona.
tanguy_k,

51

Soluzione semplice: - (non è necessario effettuare alcun metodo)

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

2
Funziona bene per me. Grazie!
HankScorpio,

17

Puoi semplicemente chiamare un metodo sul tuo ambito per invertirlo per te, in questo modo:

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

Si noti che $scope.reversecrea una copia dell'array poiché Array.prototype.reversemodifica l'array originale.


13

se si utilizza 1.3.x, è possibile utilizzare quanto segue

{{ orderBy_expression | orderBy : expression : reverse}}

Esempio Elenco dei libri per data di pubblicazione in ordine decrescente

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

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


11

Se si utilizza angularjs versione 1.4.4 e successive , un modo semplice per ordinare è usare " $ index ".

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

guarda la demo


1

Quando si utilizza MVC in .NET con Angular è sempre possibile utilizzare OrderByDecending () quando si esegue la query db in questo modo:

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

Quindi dal lato angolare, sarà già invertito in alcuni browser (IE). Quando si supportano Chrome e FF, è quindi necessario aggiungere orderBy:

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

In questo esempio, dovresti ordinare in ordine decrescente sulla proprietà .Id. Se stai utilizzando il paging, questo diventa più complicato perché verrà ordinata solo la prima pagina. Dovresti gestirlo tramite un file di filtro .js per il tuo controller o in qualche altro modo.


0

Puoi anche usare .reverse (). È una funzione di matrice nativa

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


Il tuo voto negativo può significare solo una cosa: hai più dati in arrivo. Se {} o [] continua a ricevere dati, si invertirà ogni volta, ovviamente. È un nuovo riassunto
Pian0_M4n

Avvertenza per chiunque voglia utilizzarlo: reverseinverte l'array in posizione, non restituisce solo una copia invertita. Ciò significa che ogni volta che viene valutato, l'array verrà invertito.
jcaron,

0

Questo perché stai usando JSON Object. Quando si affrontano tali problemi, modificare l'oggetto JSON in JSON Array Object.

Per esempio,

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


0

Ho trovato qualcosa del genere, ma invece di array uso oggetti.

Ecco la mia soluzione per gli oggetti:

Aggiungi filtro personalizzato:

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

Che può quindi essere usato come

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

Se hai bisogno del vecchio supporto del browser, dovrai definire la funzione di riduzione (disponibile solo in 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

Mi ero frustrato con questo problema e quindi ho modificato il filtro creato da @Trevor Senior mentre stavo incontrando un problema con la mia console dicendo che non poteva usare il metodo inverso. Volevo anche mantenere l'integrità dell'oggetto perché questo è ciò che Angular utilizza originariamente in una direttiva ng-repeat. In questo caso ho usato l'input di stupid (key) perché la console si arrabbierà dicendo che ci sono duplicati e nel mio caso ho dovuto tenere traccia di $ index.

Filtro:

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

Sto aggiungendo una risposta che nessuno ha menzionato. Proverei a farlo fare al server se ne hai uno. Il filtro client può essere pericoloso se il server restituisce molti record. Perché potresti essere costretto ad aggiungere il paging. Se si dispone di paging dal server, il filtro client in ordine sarebbe nella pagina corrente. Il che confonderebbe l'utente finale. Quindi, se hai un server, invia l'ordine con la chiamata e lascia che il server lo restituisca.


0

Suggerimento utile:

Puoi invertire il tuo array con Js alla vaniglia: yourarray .reverse ()

Attenzione: il contrario è distruttivo, quindi cambierà l'array, non solo la variabile.


-2

Vorrei solo usare il metodo inverso nativo dell'array è sempre una scelta migliore sulla creazione di filtri o sull'utilizzo $index.

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

Plnkr_demo .


Stai invertendo l'array originale ... Una pratica migliore sarebbe quella di restituire un nuovo array che è invertito.
Vandervidi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.