鉴于我有以下对象:
{
"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),我如何按最短曲目,专辑总长度或专辑曲目的最短平均长度订购专辑?
如果我要添加另一个乐队,我将如何通过这些过滤器(最短曲目/专辑长度/平均曲目长度)自行订购乐队?
答案 0 :(得分:2)
排序数字字符串是一种痛苦,但我们仍然可以解决它。这是一个给出以下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
,我们需要在当前Scope
上传递函数(不是函数的结果),该函数将用于返回值正在分类;在这种情况下`orderBy:shortestTrackByAlbum&#39;。
$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上的文档,更具体地说是Angular's OrderBy。