如何根据 AngularJS 中的子结果集对结果进行排序
How do I order results based on a child set of results in AngularJS
鉴于我有以下对象:
{
"bands": [{
"name": "The Wibbles",
"formed": 1992,
"albums": [{
"name": "A New Wibble",
"songs": [{
"name": "Song One",
"time": "3:12"
}, {
"name": "Song Two",
"time": "2:34"
}, {
"name": "Song Three",
"time": "2:21"
}, {
"name": "Song Four",
"time": "3:44"
}, {
"name": "Song Five",
"time": "3:54"
}]
}, {
"name": "The Wibbles Strike Back",
"songs": [{
"name": "Song Six",
"time": "8:12"
}, {
"name": "Song Seven",
"time": "7:34"
}, {
"name": "I Killed a Girl",
"time": "8:21"
}, {
"name": "Monkey Fighters",
"time": "7:44"
}, {
"name": "Funkallica",
"time": "9:54"
}]
}]
}]
}
使用 AngularJS(可能还有 underscore.js),我如何按最短曲目、专辑总长度或专辑曲目的最短平均长度对专辑进行排序?
如果我要添加另一个乐队,我将如何通过这些过滤器(最短曲目/专辑长度/平均曲目长度)对乐队本身进行排序?
排序数字字符串有点麻烦,但我们仍然可以解决它。这是给出以下 html:
的示例
<div ng-repeat="band in bands">
<h1>{{ band.name }}</h1>
<div ng-repeat="album in band.albums">
<h2>{{ album.name }}</h2>
<ul>
<li ng-repeat="songs in album.songs">
<h3>{{ song.name }}</h3>
<em>{{ song.time }}</em>
</li>
</div>
</div>
现在,要按最短曲目排序专辑:
<div ng-repeat="band in bands">
<h1>{{ band.name }}</h1>
<div ng-repeat="album in band.albums | orderBy:shortestTrackByAlbum">
<h2>{{ album.name }}</h2>
<ul>
<li ng-repeat="song in album.songs">
<h3>{{ song.name }}</h3>
<em>{{ song.time }}</em>
</li>
</ul>
</div>
</div>
如您所见,为了执行自定义 orderBy
,我们需要在将用于 return 正在排序的值;在本例中为“orderBy:shortestTrackByAlbum”。
$scope.bands = [...];
$scope.shortestTrackByAlbum = function(album) {
var times = [];
for (var i = 0; i < album.songs.length; i++) {
var minutesAndSeconds = album.songs[i].split(':'),
m = parseInt(minutesAndSeconds[0], 10),
s = parseInt(minutesAndSeconds[1], 10);
times.push(m * 60 + s);
}
return Math.min.apply(null, times);
};
根据你提供的数据,我将你的时间换算成秒,找出曲目中秒数最小的。然后将这个最小的数字与其他专辑的最小的数字进行比较,以对所有这些最小的数字进行排序(请原谅冗余)。
使用此模式,您应该能够为每种情况编写一个函数。请参阅此 Plunker 以获取简单示例。
此外:如果您希望用户能够更改排序,您可以执行如下操作:
<select ng-model="sortingMethod"
ng-options="m.fn as m.name for m in methods"></select>
...
<div ng-repeat="album in albums | orderBy:sortingMethod">
...
$scope.methods = [
{
name: 'Shortest Track',
fn: $scope.shortestTrackByAlbum
},
{
name: 'Total Album Length',
fn: $scope.totalAlbumLengthByAlbum
},
{
name: 'Shortest Average Length',
fn: $scope.shortestAverageLengthByAlbum
}
];
$scope.shortestTrackByAlbum = function(album) { ... };
$scope.totalAlbumLengthByAlbum = function(album) { ... };
$scope.shortestAverageLengthByAlbum = function(album) { ... };
一定要查看 Angular Filters and more specifically Angular's OrderBy 上的文档。
鉴于我有以下对象:
{
"bands": [{
"name": "The Wibbles",
"formed": 1992,
"albums": [{
"name": "A New Wibble",
"songs": [{
"name": "Song One",
"time": "3:12"
}, {
"name": "Song Two",
"time": "2:34"
}, {
"name": "Song Three",
"time": "2:21"
}, {
"name": "Song Four",
"time": "3:44"
}, {
"name": "Song Five",
"time": "3:54"
}]
}, {
"name": "The Wibbles Strike Back",
"songs": [{
"name": "Song Six",
"time": "8:12"
}, {
"name": "Song Seven",
"time": "7:34"
}, {
"name": "I Killed a Girl",
"time": "8:21"
}, {
"name": "Monkey Fighters",
"time": "7:44"
}, {
"name": "Funkallica",
"time": "9:54"
}]
}]
}]
}
使用 AngularJS(可能还有 underscore.js),我如何按最短曲目、专辑总长度或专辑曲目的最短平均长度对专辑进行排序?
如果我要添加另一个乐队,我将如何通过这些过滤器(最短曲目/专辑长度/平均曲目长度)对乐队本身进行排序?
排序数字字符串有点麻烦,但我们仍然可以解决它。这是给出以下 html:
的示例<div ng-repeat="band in bands">
<h1>{{ band.name }}</h1>
<div ng-repeat="album in band.albums">
<h2>{{ album.name }}</h2>
<ul>
<li ng-repeat="songs in album.songs">
<h3>{{ song.name }}</h3>
<em>{{ song.time }}</em>
</li>
</div>
</div>
现在,要按最短曲目排序专辑:
<div ng-repeat="band in bands">
<h1>{{ band.name }}</h1>
<div ng-repeat="album in band.albums | orderBy:shortestTrackByAlbum">
<h2>{{ album.name }}</h2>
<ul>
<li ng-repeat="song in album.songs">
<h3>{{ song.name }}</h3>
<em>{{ song.time }}</em>
</li>
</ul>
</div>
</div>
如您所见,为了执行自定义 orderBy
,我们需要在将用于 return 正在排序的值;在本例中为“orderBy:shortestTrackByAlbum”。
$scope.bands = [...];
$scope.shortestTrackByAlbum = function(album) {
var times = [];
for (var i = 0; i < album.songs.length; i++) {
var minutesAndSeconds = album.songs[i].split(':'),
m = parseInt(minutesAndSeconds[0], 10),
s = parseInt(minutesAndSeconds[1], 10);
times.push(m * 60 + s);
}
return Math.min.apply(null, times);
};
根据你提供的数据,我将你的时间换算成秒,找出曲目中秒数最小的。然后将这个最小的数字与其他专辑的最小的数字进行比较,以对所有这些最小的数字进行排序(请原谅冗余)。
使用此模式,您应该能够为每种情况编写一个函数。请参阅此 Plunker 以获取简单示例。
此外:如果您希望用户能够更改排序,您可以执行如下操作:
<select ng-model="sortingMethod"
ng-options="m.fn as m.name for m in methods"></select>
...
<div ng-repeat="album in albums | orderBy:sortingMethod">
...
$scope.methods = [
{
name: 'Shortest Track',
fn: $scope.shortestTrackByAlbum
},
{
name: 'Total Album Length',
fn: $scope.totalAlbumLengthByAlbum
},
{
name: 'Shortest Average Length',
fn: $scope.shortestAverageLengthByAlbum
}
];
$scope.shortestTrackByAlbum = function(album) { ... };
$scope.totalAlbumLengthByAlbum = function(album) { ... };
$scope.shortestAverageLengthByAlbum = function(album) { ... };
一定要查看 Angular Filters and more specifically Angular's OrderBy 上的文档。