Я пытаюсь отсортировать некоторые данные по свойствам. Вот пример, который, как я думал, должен работать, но это не так.
HTML-часть:
<div ng-app='myApp'>
<div ng-controller="controller">
<ul>
<li ng-repeat="(key, value) in testData | orderBy:'value.order'">
{{value.order}}. {{key}} -> {{value.name}}
</li>
</ul>
</div>
</div>
Часть JS:
var myApp = angular.module('myApp', []);
myApp.controller('controller', ['$scope', function ($scope) {
$scope.testData = {
C: {name:"CData", order: 1},
B: {name:"BData", order: 2},
A: {name:"AData", order: 3},
}
}]);
И результат:
- A -> AData
- B -> BData
- C -> CData
... это ИМХО должно выглядеть так:
- C -> CData
- B -> BData
- A -> AData
Я что-то пропустил (вот и готовый JSFiddle для экспериментов)?
источник
{1:'Example 1', 2:'Example 2', 3:'Example 3', ...}
for(var objectKey in input) { input[objectKey]['_key'] = objectKey; array.push(input[objectKey]); }
как это мы можем использовать<div ng-repeat="value in object | orderObjectBy:'order'" ng-init="key = value['_key']">
... | orderBy: 'name'
.Это довольно просто, просто сделай это вот так
$scope.props = [{order:"1"},{order:"5"},{order:"2"}] ng-repeat="prop in props | orderBy:'order'"
источник
Не забывайте, что parseInt () работает только для целочисленных значений. Чтобы отсортировать строковые значения, вам нужно поменять местами это:
array.sort(function(a, b){ a = parseInt(a[attribute]); b = parseInt(b[attribute]); return a - b; });
с этим:
array.sort(function(a, b){ var alc = a[attribute].toLowerCase(), blc = b[attribute].toLowerCase(); return alc > blc ? 1 : alc < blc ? -1 : 0; });
источник
Как видно из кода angular-JS ( https://github.com/angular/angular.js/blob/master/src/ng/filter/orderBy.js ), ng-repeat не работает с объектами. Вот хак с sortFunction.
http://jsfiddle.net/sunnycpp/qaK56/33/
<div ng-app='myApp'> <div ng-controller="controller"> <ul> <li ng-repeat="test in testData | orderBy:sortMe()"> Order = {{test.value.order}} -> Key={{test.key}} Name=:{{test.value.name}} </li> </ul> </div> </div> myApp.controller('controller', ['$scope', function ($scope) { var testData = { a:{name:"CData", order: 2}, b:{name:"AData", order: 3}, c:{name:"BData", order: 1} }; $scope.testData = _.map(testData, function(vValue, vKey) { return { key:vKey, value:vValue }; }) ; $scope.sortMe = function() { return function(object) { return object.value.order; } } }]);
источник
согласно http://docs.angularjs.org/api/ng.filter:orderBy , orderBy сортирует массив. В вашем случае вы передаете объект, поэтому вам придется реализовать свою собственную функцию сортировки.
или передать массив -
$scope.testData = { C: {name:"CData", order: 1}, B: {name:"BData", order: 2}, A: {name:"AData", order: 3}, }
взгляните на http://jsfiddle.net/qaK56/
источник
Вам действительно следует улучшить структуру JSON, чтобы решить вашу проблему:
$scope.testData = [ {name:"CData", order: 1}, {name:"BData", order: 2}, {name:"AData", order: 3}, ]
Тогда ты мог бы сделать
<li ng-repeat="test in testData | orderBy:order">...</li>
Я думаю, проблема в том, что переменные (ключ, значение) недоступны для фильтра orderBy, и вы все равно не должны хранить данные в своих ключах.
источник
Вот что я сделал, и это работает.
Я просто использовал строковый объект.
$scope.thread = [ { mostRecent:{text:'hello world',timeStamp:12345678 } allMessages:[] } {MoreThreads...} {etc....} ]
<div ng-repeat="message in thread | orderBy : '-mostRecent.timeStamp'" >
если бы я хотел отсортировать по тексту, я бы сделал
orderBy : 'mostRecent.text'
источник
Я добавлю свою обновленную версию фильтра, которая поддерживает следующий синтаксис:
ng-repeat="(id, item) in $ctrl.modelData | orderObjectBy:'itemProperty.someOrder':'asc'
app.filter('orderObjectBy', function(){ function byString(o, s) { s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties s = s.replace(/^\./, ''); // strip a leading dot var a = s.split('.'); for (var i = 0, n = a.length; i < n; ++i) { var k = a[i]; if (k in o) { o = o[k]; } else { return; } } return o; } return function(input, attribute, direction) { if (!angular.isObject(input)) return input; var array = []; for(var objectKey in input) { if (input.hasOwnProperty(objectKey)) { array.push(input[objectKey]); } } array.sort(function(a, b){ a = parseInt(byString(a, attribute)); b = parseInt(byString(b, attribute)); return direction == 'asc' ? a - b : b - a; }); return array; } })
Спасибо Армину и Джейсону за их ответы в этой ветке и Альнитаку в этой ветке .
источник
Ответ Армина + строгая проверка типов объектов и неугловых ключей, таких как
$resolve
app.filter('orderObjectBy', function(){ return function(input, attribute) { if (!angular.isObject(input)) return input; var array = []; for(var objectKey in input) { if (typeof(input[objectKey]) === "object" && objectKey.charAt(0) !== "$") array.push(input[objectKey]); } array.sort(function(a, b){ a = parseInt(a[attribute]); b = parseInt(b[attribute]); return a - b; }); return array; } })
источник
Следующее позволяет упорядочивать объекты по ключу ИЛИ по ключу внутри объекта .
В шаблоне вы можете сделать что-то вроде:
<li ng-repeat="(k,i) in objectList | orderObjectsBy: 'someKey'">
Или даже:
<li ng-repeat="(k,i) in objectList | orderObjectsBy: 'someObj.someKey'">
Фильтр:
app.filter('orderObjectsBy', function(){ return function(input, attribute) { if (!angular.isObject(input)) return input; // Filter out angular objects. var array = []; for(var objectKey in input) { if (typeof(input[objectKey]) === "object" && objectKey.charAt(0) !== "$") array.push(input[objectKey]); } var attributeChain = attribute.split("."); array.sort(function(a, b){ for (var i=0; i < attributeChain.length; i++) { a = (typeof(a) === "object") && a.hasOwnProperty( attributeChain[i]) ? a[attributeChain[i]] : 0; b = (typeof(b) === "object") && b.hasOwnProperty( attributeChain[i]) ? b[attributeChain[i]] : 0; } return parseInt(a) - parseInt(b); }); return array; } })
источник