2013-02-19 10 views
47

Supponiamo che io sono i seguenti utenti:Come ordinare l'origine dati dell'oggetto in ng-repeat in AngularJS?

$scope.users = { 
    "2": { 
    email: '[email protected]', 
    name: 'John' 
    }, 
    "3": { 
    email: '[email protected]', 
    name: 'Elisa' 
    } 
} 

vorrei creare un <select> con le seguenti opzioni:

<option value="3">Elisa</option> 
<option value="2">John</option> 

In altre parole, gli utenti devono essere ordinati per nome.

ho provato la seguente utilizzando la sintassi (key, value) in expression, ma non funziona:

<option ng-repeat="(user_id, user) in users | orderBy:'user.name'" 
     value="{{ user.id }}"> 
    {{ user.name }} 
</option> 

Live example here.

Che cosa mi manca?

Si prega di non proporre soluzioni con ng-options come io uso ui-select2 che è incompatibile con ng-options.

+0

Non abbiamo bisogno di due nuovi tag per questa domanda e questa domanda solo. Si prega di fare un favore ai tag aggiungendo un wiki appropriato e aggiungendoli ad altre domande pertinenti. Se non riesci a trovare altre domande per i tag, non è necessario che esistano due volte oltre ... – Charles

+2

'ng-repeat' e' orderBy' sono cose molto comuni in AngularJS. Credo che ci saranno molte più domande su questi due.Ma, comunque, ho aggiunto questi tag ad altre domande. –

+0

Dal momento che mi manca la reputazione di suggerire formalmente tag ortografie alternative, qualcun altro qui dovrebbe aggiungere ** angularjs-order-by **. Sembra assurdo il fatto che la scatola del cammello 'ngRepeat' diventi' ng-repeat', mentre 'orderBy' diventa' orderby'. – maurice

risposta

52

Mentre si dovrebbe vedere questo nel thread riferimenti risposta dell'autore in un link, ho pensato che sarebbe bene mettere in su una delle soluzioni alternative citate SOPRA:

È vero che questo non è tecnicamente implementato, ma c'è un facile aggiramento se sei disposto a cambiare leggermente il tuo modello di dati: usa un filtro personalizzato per generare una matrice delle proprietà dell'oggetto (senza sostituzione). Se si aggiunge il campo chiave per gli oggetti ("id" nel caso di cui sopra), si dovrebbe essere in grado di ottenere il comportamento vostra ricerca:

app.filter("toArray", function(){ 
    return function(obj) { 
     var result = []; 
     angular.forEach(obj, function(val, key) { 
      result.push(val); 
     }); 
     return result; 
    }; 
}); 
... 

$scope.users = { 
    1: {name: "John", email: "[email protected]", id: 1}, 
    2: {name: "Elisa", email: "[email protected]", id: 2} 
}; 

Ecco la direttiva ng-repeat che potrebbe essere utilizzato:

<option value="{{user.id}}" ng-repeat="user in users | toArray | orderBy:'name'">{{user.name}}</option> 

Ed ecco il plunkr.

Si noti che il filtro orderBy accetta name come parametro e non user.name.

Sfortunatamente, l'aggiunta della proprietà id ai propri oggetti crea potenziali problemi di incompatibilità con la chiave nell'oggetto contenitore.

Nel link che lei ha citato nella sua risposta, ci sono anche proposte soluzioni che creano la proprietà id negli oggetti di utente al volo, ma mi sento come questo approccio è un po 'meno disordinato (a costo di introdurre la replica dei dati).

+0

@BarthZalewski Ciò sembra buono tuttavia come mai se provo a invertire il filtro non cambia nulla? riesci a gestire l'inversione di tendenza come una situazione? ng-repeat = "utente negli utenti | toArray | orderBy: 'name': reverse" – ak85

+0

Funziona anche quando si utilizza la (chiave, valore) negli utenti. Molto bene! –

+1

In risposta alla domanda di @ ak85 si userebbe ng-repeat = "utente negli utenti | toArray | orderBy: 'name': true" per invertire la lista. Boolean true identifica un ordine inverso. – Doug

9

OK, ho trovato la risposta:

It is not implemented yet :(

+9

Potrebbe anche valere la pena ricordare che non ci sono piani per implementarlo in base al thread che citi. – mhess

0

Aggiungendo alla risposta accettata e di vedere il formato dei dati, si dovrebbe trasformare i vostri dati come

app.filter('myFilterUsers',function(){ 
    return function(data) 
    { 
     var newRes = []; 
     angular.forEach(data,function(val,key){ 
      val["id"] = key; //Add the ID in the JSON object as you need this as well. 
      newRes.push(val); 
     }); 
     return newRes; 
    } 
}); 
Problemi correlati