Apa yang saya coba lakukan adalah mengurutkan data dengan properti. Berikut adalah contoh yang saya pemikiran manusia harus bekerja, tapi itu doesn't.
Bagian 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 bagian:
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},
}
}]);
Dan hasilnya:
- A -> AData
- B -> BData
- C -> CData
... bahwa IMHO harus terlihat seperti ini:
- C -> CData
- B -> BData
- A -> AData
Apa aku melewatkan sesuatu (di sini siap [JSFiddle][1] untuk bereksperimen pada)?
AngularJS' orderBy filter tidak hanya mendukung array - tidak ada benda-benda. Jadi, anda harus menulis sendiri filter kecil, yang melakukan pemilahan untuk anda.
Atau mengubah format data yang anda tangani dengan (jika anda memiliki pengaruh pada). Array yang berisi benda-benda yang diurutkan oleh penduduk asli orderBy filter.
Di sini saya orderObjectBy filter untuk AngularJS:
app.filter('orderObjectBy', function(){
return function(input, attribute) {
if (!angular.isObject(input)) return input;
var array = [];
for(var objectKey in input) {
array.push(input[objectKey]);
}
array.sort(function(a, b){
a = parseInt(a[attribute]);
b = parseInt(b[attribute]);
return a - b;
});
return array;
}
});
Penggunaan dalam pandangan anda:
<div class="item" ng-repeat="item in items | orderObjectBy:'position'">
//...
</div>
Objek kebutuhan dalam contoh ini posisi atribut, tetapi anda memiliki fleksibilitas untuk menggunakan atribut pada objek (yang berisi sebuah bilangan bulat), hanya dengan definisi di lihat.
Contoh JSON:
{
"123": {"name": "Test B", "position": "2"},
"456": {"name": "Test A", "position": "1"}
}
Berikut ini adalah biola yang menunjukkan penggunaan:
Don't lupa bahwa parseInt() hanya bekerja untuk nilai Integer. Untuk mengurutkan nilai-nilai string yang anda butuhkan untuk swap ini:
array.sort(function(a, b){
a = parseInt(a[attribute]);
b = parseInt(b[attribute]);
return a - b;
});
dengan ini:
array.sort(function(a, b){
var alc = a[attribute].toLowerCase(),
blc = b[attribute].toLowerCase();
return alc > blc ? 1 : alc < blc ? -1 : 0;
});
Seperti yang anda lihat dalam kode-angular JS ( https://github.com/angular/angular.js/blob/master/src/ng/filter/orderBy.js ) ng-repeat tidak bekerja dengan benda-benda. Berikut adalah hack dengan sortFunction.
<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;
}
}
}]);
menurut http://docs.angularjs.org/api/ng.filter:orderBy , orderBy macam array. Dalam kasus anda, anda're melewati sebuah objek, sehingga Anda'll harus melaksanakan sendiri fungsi sorting.
atau melewati array -
$scope.testData = {
C: {name:"CData", order: 1},
B: {name:"BData", order: 2},
A: {name:"AData", order: 3},
}
lihatlah
Anda harus benar-benar meningkatkan struktur JSON untuk memperbaiki masalah anda:
$scope.testData = [
{name:"CData", order: 1},
{name:"BData", order: 2},
{name:"AData", order: 3},
]
Kemudian anda bisa melakukan
<li ng-repeat="test in testData | orderBy:order">...</li>
Masalahnya, saya pikir, adalah bahwa (key, value) variabel tidak tersedia untuk orderBy filter, dan anda tidak harus menyimpan data di kunci lagian
Berikut adalah apa yang saya lakukan dan itu bekerja. Saya hanya menggunakan stringified objek.
$scope.thread = [
{
mostRecent:{text:'hello world',timeStamp:12345678 }
allMessages:[]
}
{MoreThreads...}
{etc....}
]
<div ng-repeat="pesan di thread | orderBy : '-mostRecent.timeStamp'" >
jika saya ingin mengurutkan berdasarkan teks yang akan saya lakukan
orderBy : 'mostRecent.text'
Saya akan menambahkan versi upgrade dari filter yang mampu mendukung sintaks berikutnya:
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;
}
})
Terima kasih untuk Armin dan Jason untuk jawaban mereka di thread ini, dan Alnitak di thread ini.
Armin's jawaban + pemeriksaan ketat untuk jenis objek dan non-sudut kunci seperti $tekad
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;
}
})
Berikut memungkinkan untuk memesan benda dengan kunci ATAU dengan kunci di dalam suatu benda.
Di template anda dapat melakukan sesuatu seperti:
<li ng-repeat="(k,i) in objectList | orderObjectsBy: 'someKey'">
Atau bahkan:
<li ng-repeat="(k,i) in objectList | orderObjectsBy: 'someObj.someKey'">
Filter:
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;
}
})