我的嵌套json正在杀了我,似乎我必须编写一个自定义过滤器来执行orderBy
$scope.ranking = [
{
'uId': 2,
'name': 'Jeremy',
'tabs': [{
'tabId': 1,
'points': 100,
}, {
'tabId': 2,
'points': 10
}],
},
{
'uId': 3,
'name': 'Jordon',
'tabs': [{
'tabId': 1,
'points': 180,
},{
'tabId': 2,
'points': 5
}],
}]
}
我想要的是排序用户'按分数排名。如果选项卡包含单个点,则会很容易,但是多个选项卡指示它们所玩的游戏类型。
看看我的小提琴,然后你就会知道我尝试做什么,http://jsfiddle.net/U4dd8/
我写了自定义过滤器,直到这里
app.filter("rankFilter", function(){
return function (input, points) {
var output = [];
for (var i in input) {
for(var j in input[i].tabs){
var points = input[i].tabs[j].points;
output.push(points);
}
}
return output;
};
答案 0 :(得分:1)
如果我理解正确,您希望在每个标签中显示具有该类别点数的用户,并按点(针对该特定类别)对其进行排序。
这是一个非常本地化的问题(而不是不与Angular相关),但这是一个可能的解决方案:
<强> HTML:强>
<li ng-repeat="user in ranking | orderByPointsForTab:currentTab">
<a ng-click="showFriendsTasksEvent(user.uId)">
{{user.name}} {{user.tabs | pointsForTab:currentTab}}
</a>
</li>
使用了2个过滤器:
pointsForTab
:它需要一个tabs
数组和currentTab
作为参数,并返回与当前标签相关联的点。
这也可以是控制器中的一个功能。
orderByPointsForTab
:它需要users
数组和currentTab
作为参数,并返回一个新数组,其中只包含具有当前选项卡的点并按降序排序的用户点数(对于当前标签)。
<子>
为了理解下面的代码,您应该熟悉Array
的以下方法(标准JS - 没有Angular特定的):
子> <子>
- Array.prorotype.forEach
- Array.prorotype.some
- Array.prorotype.map
- Array.prorotype.sort
子>
app.filter("orderByPointsForTab", function () {
/* `users` and `currentTab` as input */
return function (users, currentTab) {
/* 1: Create an array of users that have points
* for current tab (in random order) */
var unsortedUsersWithPoints = [];
(users || []).forEach(function (user) {
/* Iterate over the tabs of each user... */
(user.tabs || []).some(function (tab) {
/* ...until we find the current tab... */
if (tab.tabId === currentTab) {
/* ...store the user and the points for current tab
* for later access (see below)... */
unsortedUsersWithPoints.push({
user: user,
points: tab.points
});
/* ...and break the loop for the current user */
return true;
}
});
});
/* 2: Sort the array of `{user, points}` objects
* in descending order of points */
var sortedUsersWithPoints = unsortedUsersWithPoints.sort(
function (obj1, obj2) {
return obj2.points - obj1.points;
}
);
/* 3: Create a new array containing only `user` objects,
* but keeping the order in `sortedUsersWithPoints` (see above) */
var output = sortedUsersWithPoints.map(function (obj) {
return obj.user;
});
/* 4. Return the sorted `users` array */
return output;
};
});
上述代码可在此 short demo 。
中找到答案 1 :(得分:0)
首先,由于您已在视图中显示currentTab
,因此您可以使用users
选择要为每个标签显示的ng-show
,而不是使用额外的过滤器。然后,使用自定义过滤器(orderByPoints
)实现自定义排序,根据标签点对用户进行排序。
您的观点变为
<div ng-controller="AppCtrl">
<button ng-click="currentTab=1">shooting</button>
<button ng-click="currentTab=2">dribble</button>
<p>Leaderboard</p>
<ul>
<li ng-repeat="user in ranking | orderByPoints: currentTab">
<span ng-repeat="tab in user.tabs">
<span ng-show="tab.tabId == currentTab">
<a ng-click="showFriendsTasksEvent(user.uId)">
{{ user.name }} - {{ tab.points }}
</a>
</span>
</span>
</li>
</ul>
</div>
自定义过滤器
app.filter("orderByPoints", function () {
var inputTab;
function compare(a, b) {
// Check for undefined since value may be missing for some users
if (typeof a.tabs[inputTab] != 'undefined' && typeof b.tabs[inputTab] != 'undefined')
return b.tabs[inputTab].points - a.tabs[inputTab].points;
return 0;
}
// Filter function
return function (input, currentTab) {
inputTab = currentTab; // Get current tab
return input.sort(compare); // Call custom sort
}
});
以下是更新的Fiddle(我添加了额外的user
和标签以供演示)。