2013-02-19 14 views
47

Załóżmy, że mam następujących użytkowników:Jak posortować źródło danych obiektu w ng-repeat w AngularJS?

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

Chciałbym stworzyć <select> z następujących opcji:

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

Innymi słowy, użytkownicy powinni być sortowane według nazwy.

Próbowałem następujących używając składni (key, value) in expression, ale to nie działa:

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

Live example here.

Czego mi brakuje?

Nie sugeruj rozwiązań z ng-options, ponieważ używam ui-select2, który jest niezgodny z ng-options.

+0

Nie potrzebujemy dwa nowe tagi na to pytanie i to pytanie tylko. Prosimy o tagowanie przysług, dodając odpowiednią wiki i dodając je do innych istotnych pytań. Jeśli nie możesz znaleźć innych pytań do tagów, to nie muszą istnieć dwa razy w ciągu ... – Charles

+2

'ng-repeat' i' orderBy' są bardzo często używane w AngularJS. Wierzę, że będzie o wiele więcej pytań dotyczących tych dwóch.Ale w każdym razie dodałem te znaczniki do innych pytań. –

+0

Ponieważ brakuje mi reputacji, która formalnie sugeruje alternatywne pisownie tagów, ktoś inny powinien dodać ** angularjs-order-by **. Wydaje się bezsensowne, że wielbłądziek "ngRepeat" stanie się 'ng-repeat', a' orderBy' stanie się 'orderby'. – maurice

Odpowiedz

52

Chociaż można zobaczyć to w wątku referencje odpowiedź autora w link, myślałem, że byłoby dobrze, aby umieścić jedną z wymienionych obejścia Na przykład:

To prawda, że ​​nie jest to technicznie zaimplementowane, ale jeśli chcesz zmienić nieco model danych, możesz łatwo wykonać pracę: użyj niestandardowego filtru, aby wygenerować tablicę właściwości obiektu (bez wymiany). Jeśli dodać pole klucza do obiektów („id” w powyższym przypadku), powinieneś być w stanie uzyskać zachowanie szukasz:

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

Oto dyrektywa ng-repeat, które mogą być wykorzystane:

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

A tutaj jest plunkr.

Należy zauważyć, że filtr orderBy przyjmuje jako parametr name, a nie user.name.

Niestety, dodanie właściwości id do twoich obiektów powoduje potencjalne niedopasowanie za pomocą swojego klucza w obiekcie zawierającym.

W linku, o którym wspomniałeś w swojej odpowiedzi, są również proponowane rozwiązania, które tworzą właściwość id w obiektach użytkownika w locie, ale wydaje mi się, że to podejście jest nieco mniej kłopotliwe (kosztem wprowadzenia replikacji danych).

+0

@BarthZalewski To wygląda dobrze, ale jak to się stanie, jeśli spróbuję odwrócić filtr nic się nie zmieni? czy potrafisz poradzić sobie z odwrotnością i sytuacją? ng-repeat = "użytkownik w użytkownikach | toArray | orderBy: 'name': reverse" – ak85

+0

Działa to również podczas korzystania z podejścia (key, value) w przypadku użytkowników. Dobra robota! –

+1

W odpowiedzi na pytanie @ ak85 użyłbyś ng-repeat = "user in users | toArray | orderBy: 'name': true" aby odwrócić listę. Wartość logiczna prawda identyfikuje kolejność odwrotną. – Doug

0

Dodawanie do zaakceptowanej odpowiedzi i widząc swój format danych, należy przekształcić swoje dane jako

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; 
    } 
}); 
Powiązane problemy