2012-11-25 3 views
8

У меня есть объект, как это:сортировочные значения хэш-объекта в ngRepeat - angularJS

$scope.phones = new Object(); 
$scope.phones['id1'] = { 
    "name":"Phone Name1", 
    "dateReleased":"2012-1-09 15:48:24" 
}; 
$scope.phones['id2'] = { 
    "name": "Phone Name2", 
    "dateReleased":"2012-3-12 15:32:11" 
}; 
$scope.phones['id3'] = { 
    "name": "Phone Name3", 
    "dateReleased":"2012-2-10 13:53:32" 
}; 

Я отображая это с помощью ngRepeat. Я не могу заказать dateReleased. Кроме того, порядок в обратном порядке не работает. Мой ngRepeat выглядит это:

<li ng-repeat="phone in phones | orderBy:dateReleased:true"> 
    <p>{{phone.name}}</p> 
    <p>{{phone.dateReleased}}</p> 
</li> 

ответ

5

Если вы проверяете documentation он говорит, что выражение в OrderBy может быть функцией, строки или массива. Поэтому вам нужно dateReleased быть строкой: 'dateReleased'

Также вам нужны ваши телефоны. Объект будет фактическим массивом.

Try:

$scope.phones = [{ 
     "name":"Phone Name1", 
     "dateReleased":"2012-1-09 15:48:24" 
    },{ 
     "name": "Phone Name2", 
     "dateReleased":"2012-3-12 15:32:11" 
    },{ 
     "name": "Phone Name3", 
     "dateReleased":"2012-2-10 13:53:32" 
    }]; 

<li ng-repeat="phone in phones | orderBy:'dateReleased':true"> 
    <p>{{phone.name}}</p> 
    <p>{{phone.dateReleased}}</p> 
</li> 
+0

working: http://jsfiddle.net/e2ed7/ – mb21

2

Прежде всего, вы должны понять, что ng:filter и ng:orderBy работа с массивами (упорядоченная коллекция элементов), но вы пытаетесь использовать их на объект (_un_ordered коллекция предметов). Один из возможных подходов состоит в том, чтобы собрать все объекты в массив, а затем продолжить с ним ng-repeat. Как это:

<ul ng-init="phones = [ 
     {name:'Phone Name 1', dateReleased:'2011-1-09 15:48:24'} 
    , {name:'Phone Name 2', dateReleased:'2012-3-12 15:32:11'} 
    , {name:'Phone Name 3', dateReleased:'2012-2-10 13:53:32'}]; 
    pred = '-dateReleased';" > 
    <li ng-repeat="phone in phones | orderBy:pred"> 
     <p>{{phone.name}}</p> 
     <p>{{phone.dateReleased}}</p> 
    </li> 
</ul> 
3

И другие ответы, чтобы вы часть пути, но не весь путь ...

Вам нужно создать функцию в Вашей области, которая преобразует объект в массив, как так:

$scope.phonesArray = function() { 
    var result = []; 
    angular.forEach($scope.phones, function(phone, id) { 
     result.push(phone); 
    }); 
    return result; 
}; 

Тогда вы назвали бы, что вместо вашего объекта в вашем ngRepeat:

<li ng-repeat="phone in phonesArray() | orderBy:'dateReleased':true"> 
    <p>{{phone.name}}</p> 
    <p>{{phone.dateReleased}}</p> 
</li> 

Также: Обратите внимание, что 'dateReleased' является строкой, поэтому он знает, что $ eval это строка от текущего элемента, иначе он проверит родительский объект $ scope.dateReleased, которого не существует.

Here is a plunk for what I think you're trying to do

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

12

В то время как ngRepeat может перебирать хеш-объект, например $scope.phones, встроенный фильтр orderBy не будет работать. Я считаю, что это связано с тем, как хранятся объекты. Как отмечали другие, вам нужно преобразовать хэш в массив. Хотя вы можете сделать это, используя методы, предложенные выше, я предпочитаю делать это с помощью настраиваемого фильтра. Это дает мне преимущество в том, что мне не нужно напрямую изменять свой хэш, а также давайте снова использовать фильтр с другими хэшами.

yourApp.filter('orderObjectBy', function() { 
    return function(items, field, reverse) { 
    var filtered = []; 
    angular.forEach(items, function(item) { 
     filtered.push(item); 
    }); 
    filtered.sort(function (a, b) { 
     return (a[field] > b[field] ? 1 : -1); 
    }); 
    if(reverse) filtered.reverse(); 
    return filtered; 
    }; 
}); 

Этот фильтр преобразует объект в стандартный массив и сортирует его по указанному вами полю.Вы можете использовать фильтр orderObjectBy точно так же, как orderBy, включая логическое значение после имени поля, чтобы указать, должен ли порядок быть отменен. Другими словами, false возрастает, true нисходит.

<li ng-repeat="phone in phones | orderObjectBy:'dateReleased':true"> 
    <p>{{phone.name}}</p> 
    <p>{{phone.dateReleased}}</p> 
</li> 

У меня post on my blog по этой теме.

+0

Код из вашего сообщения в блоге не работает, в то время как этот делает ... странно :) Спасибо, чувак, спас мне жизнь! – hakazvaka

Смежные вопросы