it-swarm.com.ru

Как отсортировать объектный источник данных в ng-repeat в AngularJS?

Предположим, у меня есть следующие пользователи:

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

Я хотел бы создать <select> со следующими параметрами:

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

Другими словами, пользователи должны быть отсортированы по имени.

Я попробовал следующее, используя синтаксис (key, value) in expression , но он не работает:

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

Живой пример здесь.

Что мне не хватает?

Пожалуйста, не предлагайте решения с ng-options, так как я использую ui-select2 , который несовместим с ng-options.

47
Misha Moroshko

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

Это правда, что это технически не реализовано, но есть простой способ обойти, если вы хотите немного изменить свою модель данных: используйте пользовательский фильтр для генерации массива свойств объекта (без замены). Если вы добавите ключевое поле к объектам («id» в приведенном выше случае), вы сможете получить поведение, которое вы ищете:

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

Вот директива ng-repeat, которую можно использовать:

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

А вот и plunkr .

Обратите внимание, что фильтр orderBy принимает name в качестве параметра, а не user.name.

К сожалению, добавление свойства id к вашим объектам может привести к несоответствию его ключа в содержащем объекте. 

В ссылке, которую вы упомянули в своем ответе, есть также предлагаемые решения, которые создают свойство id в пользовательских объектах на лету, но я чувствую, что этот подход немного менее грязный (за счет внедрения репликации данных).

54
mhess

ОК, я нашел ответ: 

Это еще не реализовано :(

9
Misha Moroshko

Добавляя к принятому ответу и видя ваш формат данных, вы должны преобразовать свои данные как

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