Angularjs OrderBy sur ng-repeat ne fonctionne pas

J'essaie D'utiliser AngularJS pour mon premier projet (un gestionnaire de tournois) et le filtre orderBy sur ng-repeat ne fonctionne pas: (j'ai lu toute la documentation sur ce , mais rien à faire: /

donc, j'ai des var définies sur $scope comme ça:

$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,
  },
  [...]
};

maintenant, à mon avis, j'essaie de réorganiser (d'abord avec un seul article de commande) mais ne fonctionne jamais...

<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>

la deuxième fois, je veux réorganiser à partir de 2 éléments d'information: count_win et goal_average si les premiers sont égaux.. J'essaie de remplacer $scope.order_item comme ça, mais si avec un seul le code ne fonctionne pas, il ne fonctionnera jamais avec 2...

$scope.order_item = ['count_win','goal_average'];

Merci à vous tous pour la lecture et désolé pour la taille de la publication.

34
demandé sur JSK NS 2014-05-28 23:13:33

3 réponses

$scope.teams n'est pas un tableau (c'est un objet d'objets), et le orderBy filtre ne fonctionne qu'avec des tableaux. Si vous faites $scope.teams un tableau, il fonctionnera:

$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,
     }
];

ou, vous pouvez ajouter un filtre spécial qui fonctionne sur des objets, comme ceci (emprunté à ici ):

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;
  };
});

et l'utiliser comme ceci:

<tr ng-repeat="team in teams | orderObjectBy:order_item:order_reverse">

Notez que ce filtre ne fonctionnera pas avec un tableau de classez les ordres comme dans la deuxième partie de votre question.

53
répondu Jerrad 2014-12-29 10:19:26

vous n'avez pas à créer un paramètre scope pour votre orderBy, vous pouvez le faire directement dans votre markup si vous avez affaire à des tableaux.

<tr ng-repeat="team in teams | orderBy:count_win:false">

avec deux paramètres, vous devez juste faire

<tr ng-repeat="team in teams | orderBy:['count_win','goal_average']">

après pour un ordre plus complexe, vous pourriez créer une fonction dans votre portée comme ceci:

$scope.customOrder = function (team) {
    //custom
}

et appelez ça comme

<tr ng-repeat="team in teams | orderBy:customOrder">

comme @Jerrad a dit, ng-repeat seulement fonctionne avec des tableaux, donc vous avez besoin de convertir votre objet teams en tableau pour le faire fonctionner correctement.

10
répondu Aperçu 2015-12-07 20:42:10

ng-repeat ne fonctionne que sur les tableaux, et pas sur des objets JSON. Cela a déjà été discuté ici: angulaire-ne peut pas faire ng - ordre de répétition de travail

vous devez soit changer l'objet JSON en tableau, soit le convertir à la volée. Le contrôleur pourrait alors ressembler à ceci:

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';
});

j'ai créé un violon ici avec une démo contenant vos données:

http://jsfiddle.net/c3VVL/

8
répondu meberhard 2017-05-23 12:17:31