Angularjs OrderBy на ng-repeat не работает
Я пытаюсь использовать AngularJS для своего первого проекта (менеджер турниров), а фильтр orderBy
на ng-repeat
не работает:( Я прочитал все документацию об этом, но нечего делать:/
Итак, у меня есть vars, определенные на $scope
следующим образом:
$scope.order_item = "count_win";
$scope.order_reverse = false;
$scope.teams = {
100 : {
id: 100,
name: "XXX",
count_win: 1,
count_loose: 2,
goal_average: 1,
},
200 : {
id: 200,
name: "XXX",
count_win: 1,
count_loose: 2,
goal_average: 1,
},
[...]
};
Теперь, по моему мнению, я пытаюсь изменить порядок (сначала только с одним элементом заказа), но никогда не работает...
<tr ng-repeat="team in teams | orderBy:order_item:order_reverse">
<td>{{team.name}}</td>
<td>{{team.count_loose}}</td>
<td>{{team.goal_average}}</td>
</tr>
Во второй раз, я хочу переупорядочить из 2-х частей информации: count_win
и goal_average
, если первые равны. Я пытаюсь заменить $scope.order_item
таким образом, но если с одним код не работает, он никогда не будет работать с 2...
$scope.order_item = ['count_win','goal_average'];
Спасибо всем за чтение и извините за размер сообщения.
Ответы
Ответ 1
$scope.teams
не является массивом (это объект объектов), а фильтр orderBy
работает только с массивами. Если вы создадите массив $scope.teams
, он будет работать:
$scope.teams = [
{
id: 100,
name: "team1",
count_win: 3,
count_loose: 2,
goal_average: 2,
},
{
id: 200,
name: "team2",
count_win: 3,
count_loose: 2,
goal_average: 1,
},
{
id: 300,
name: "team3",
count_win: 1,
count_loose: 2,
goal_average: 1,
}
];
Или вы можете добавить специальный фильтр, который работает на объектах, например этот (заимствованный из здесь):
app.filter('orderObjectBy', function() {
return function(items, field, reverse) {
var filtered = [];
angular.forEach(items, function(item) {
filtered.push(item);
});
filtered.sort(function (a, b) {
return (a[field] > b[field] ? 1 : -1);
});
if(reverse) filtered.reverse();
return filtered;
};
});
И используйте его следующим образом:
<tr ng-repeat="team in teams | orderObjectBy:order_item:order_reverse">
Обратите внимание, что этот настраиваемый фильтр не будет работать с массивом порядков сортировки, как во второй части вашего вопроса.
Ответ 2
Вам не нужно создавать параметр области для вашего заказа, вы можете прямо сделать это в своей разметке, если вы имеете дело с массивами.
<tr ng-repeat="team in teams | orderBy:count_win:false">
С двумя параметрами вы должны просто сделать
<tr ng-repeat="team in teams | orderBy:['count_win','goal_average']">
После более сложного порядка вы можете создать функцию в своей области следующим образом:
$scope.customOrder = function (team) {
//custom
}
И просто назовите его
<tr ng-repeat="team in teams | orderBy:customOrder">
Как сказал @Jerrad, ng-repeat
работает только с массивами, поэтому вам нужно преобразовать объект команд в массив, чтобы он работал правильно.
Ответ 3
ng-repeat работает только на массивах, а не на объектах JSON.
Это уже обсуждалось здесь: Angular - Невозможно выполнить операцию orderby ng-repeat
Вам либо нужно изменить объект JSON на массив, либо преобразовать его на лету.
Затем контроллер мог бы выглядеть так:
var app = angular.module('app', []);
app.controller('Ctrl', function ($scope) {
$scope.teams = [
{
id: 100,
name: "A Team",
count_win: 1,
count_loose: 2,
goal_average: 1
},
{
id: 200,
name: "C Team",
count_win: 2,
count_loose: 3,
goal_average: 4
},
{
id: 300,
name: "B Team",
count_win: 4,
count_loose: 1,
goal_average: 8
}
];
$scope.predicate = 'name';
});
Я создал скрипку здесь с демонстрацией, содержащей ваши данные:
http://jsfiddle.net/c3VVL/