Угловой - не может заставить ng-повторить работу orderBy
Я пробовал много примеров ng-repeat с orderBy, но я не могу заставить мой json работать с ним.
<div ng-app>
<script type="text/javascript" src="http://code.angularjs.org/1.0.1/angular-1.0.1.js"></script>
<div ng:controller="Main">
<div ng-repeat="release in releases| orderBy:'environment_id'">
{{release.environment_id}}
</div>
</div>
</div>
и JSON
function Main($scope) {
$scope.releases = {
"tvl-c-wbap001 + tvl-webapp": {
"timestamp": " 05:05:53 PM ",
"environment_id": "CERT5",
"release_header": "Projects/Dev",
"date": "19 Oct",
"release": "12.11.91-1"
},
"tvl-c-wbap401 + tvl-webapp": {
"timestamp": " 10:07:25 AM ",
"environment_id": "CERT4",
"release_header": "Future Release",
"date": "15 Oct",
"release": "485-1"
},
"tvl-c-wbap301 + tvl-webapp": {
"timestamp": " 07:59:48 AM ",
"environment_id": "CERT3",
"release_header": "Next Release",
"date": "15 Oct",
"release": "485-1"
},
"tvl-c-wbap201 + tvl-webapp": {
"timestamp": " 03:34:07 AM ",
"environment_id": "CERT2",
"release_header": "Next Changes",
"date": "15 Oct",
"release": "13.12.3-1"
},
"tvl-c-wbap101 + tvl-webapp": {
"timestamp": " 12:44:23 AM ",
"environment_id": "CERT1",
"release_header": "Production Mirror",
"date": "15 Oct",
"release": "13.11.309-1"
},
"tvl-s-wbap002 + tvl-webapp": {
"timestamp": " 12:43:23 AM ",
"environment_id": "Stage2",
"date": "15 Oct",
"release": "13.11.310-1"
},
"tvl-s-wbap001 + tvl-webapp": {
"timestamp": " 11:07:38 AM ",
"environment_id": "Stage1",
"release_header": "Production Mirror",
"date": "11 Oct",
"release": "13.11.310-1"
},
"tvl-p-wbap001 + tvl-webapp": {
"timestamp": " 11:39:25 PM ",
"environment_id": "Production",
"release_header": "Pilots",
"date": "14 Oct",
"release": "13.11.310-1"
},
"tvl-p-wbap100 + tvl-webapp": {
"timestamp": " 03:27:53 AM ",
"environment_id": "Production",
"release_header": "Non Pilots",
"date": "11 Oct",
"release": "13.11.309-1"
}
}
неважно, что я пишу, я всегда получаю один и тот же заказ, или я могу сказать, нет порядка вообще.
7 ответов:
на
orderBy
работает только с массивами -- см. http://docs.angularjs.org/api/ng.filter:orderByтакже отличный фильтр для использования объектов вместо массивов @ Angularjs OrderBy на ng-repeat не работает
Как уже упоминалось, допускается только массивы. Но чтобы сделать его простым для вас, вы можете динамически преобразовать объект в массив с помощью функции piping, как показано здесь https://gist.github.com/brev/3949705
просто объявите фильтр и добавьте его в ng-repeat:)
<div ng-app="myApp"> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script> <div ng-controller="Main"> <div ng-repeat="release in releases | object2Array | orderBy:'environment_id'">{{release.environment_id}}</div> </div> <script> var app = angular.module('myApp', []).filter('object2Array', function() { return function(input) { var out = []; for(i in input){ out.push(input[i]); } return out; } }) .controller('Main',function ($scope) { $scope.releases = {"tvl-c-wbap001 + tvl-webapp":{"timestamp":" 05:05:53 PM ","environment_id":"CERT5","release_header":"Projects/Dev","date":"19 Oct","release":"12.11.91-1"},"tvl-c-wbap401 + tvl-webapp":{"timestamp":" 10:07:25 AM ","environment_id":"CERT4","release_header":"Future Release","date":"15 Oct","release":"485-1"},"tvl-c-wbap301 + tvl-webapp":{"timestamp":" 07:59:48 AM ","environment_id":"CERT3","release_header":"Next Release","date":"15 Oct","release":"485-1"},"tvl-c-wbap201 + tvl-webapp":{"timestamp":" 03:34:07 AM ","environment_id":"CERT2","release_header":"Next Changes","date":"15 Oct","release":"13.12.3-1"},"tvl-c-wbap101 + tvl-webapp":{"timestamp":" 12:44:23 AM ","environment_id":"CERT1","release_header":"Production Mirror","date":"15 Oct","release":"13.11.309-1"},"tvl-s-wbap002 + tvl-webapp":{"timestamp":" 12:43:23 AM ","environment_id":"Stage2","date":"15 Oct","release":"13.11.310-1"},"tvl-s-wbap001 + tvl-webapp":{"timestamp":" 11:07:38 AM ","environment_id":"Stage1","release_header":"Production Mirror","date":"11 Oct","release":"13.11.310-1"},"tvl-p-wbap001 + tvl-webapp":{"timestamp":" 11:39:25 PM ","environment_id":"Production","release_header":"Pilots","date":"14 Oct","release":"13.11.310-1"},"tvl-p-wbap100 + tvl-webapp":{"timestamp":" 03:27:53 AM ","environment_id":"Production","release_header":"Non Pilots","date":"11 Oct","release":"13.11.309-1"}} }); </script>
встроенный фильтр 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; }; }); <ul> <li ng-repeat="item in items | orderObjectBy:'color':true">{{ item.color }}</li> </ul>
в ответе Eike Thies выше, если мы используем подчеркивание.js, фильтр может быть упрощен до:
var app = angular.module('myApp', []).filter('object2Array', function() { return function(input) { return _.toArray(input); } });
вот версия кода @Julian Mosquera, которая также поддерживает сортировку по объекту ключ:
yourApp.filter('orderObjectBy', function () { return function (items, field, reverse) { // Build array var filtered = []; for (var key in items) { if (field === 'key') filtered.push(key); else filtered.push(items[key]); } // Sort array filtered.sort(function (a, b) { if (field === 'key') return (a > b ? 1 : -1); else return (a[field] > b[field] ? 1 : -1); }); // Reverse array if (reverse) filtered.reverse(); return filtered; }; });
вам придется переформатировать объект releases, чтобы быть array объектов. Тогда вы сможете сортировать их так, как вы пытаетесь.
orderby работает с массивами, которые содержат объекты с неизменными значениями, которые могут быть использованы в качестве фильтров, т. е.
controller.images = [{favs:1,name:"something"},{favs:0,name:"something else"}];
когда выше массив повторяется, вы можете использовать | orderBy: 'favs' для ссылки на это значение immidiately, или использовать минус перед порядком по убыванию
<div class="timeline-image" ng-repeat="image in controller.images | orderBy:'-favs'"> <img ng-src="{{ images.name }}"/> </div>