web-dev-qa-db-fra.com

Ordre angulairePar le tri par numéro sous forme de texte dans ng-repeat

J'ai ces données:

[{"id":"42","firstname":"Sarah","lastname":"Dilby","age":"40","cars":"Yaris"},
{"firstname":"Jason","lastname":"Diry","age":"5","id":"5"},
{"id":"6","firstname":"Bilson","lastname":"Berby","age":"1","cars":"Tipo"}]

Quand je commandePar id ou par âge dans une répétition multiple, il trie le nombre sous forme de texte. Comme je ne trouve pas écrit que cela pose un problème n’importe où, je suppose qu’il ya un problème avec mon code. J'ai créé ce violon: http://jsfiddle.net/vsbGH/1/ Désolé pour le modèle, mais jsfiddle n'autorise pas la zone html. Quoi qu'il en soit, c'est le code qui charge et trie les données:

//user data
app.service('People', function() {
var People = {};
People.details = [{"id":"42","firstname":"Sarah","lastname":"Dilby","age":"40","cars":"Yaris"},
                  {"firstname":"Jason","lastname":"Diry","age":"5","id":"5"},
                  {"id":"6","firstname":"Bilson","lastname":"Berby","age":"1","cars":"Tipo"}]
return People;
});

//list ctrl
controllers.listCtrl = function ($scope,People) {
 $scope.people = People.details;

 $scope.sortList = function(sortname) {
    $scope.sorter = sortname;
 }
}

Et voici la partie ng-repeat du modèle:

<tr ng-repeat="person in people | orderBy:sorter ">
        <td>{{person.id | number}}</td>
        <td>{{person.firstname}} </td>
        <td>{{person.lastname}} </td>
        <td>{{person.age | number}}</td>
        <td>{{person.cars}} </td>
 </tr>

Merci beaucoup si vous pouvez m'aider à comprendre pourquoi les données sur les nombres ne sont pas triées sous forme de nombres et pourquoi elles sont triées sous forme de texte.

32
dewd

Je pense que la solution la plus appropriée est de formater correctement les nombres que j'ai sur mes objets JSON, c'est-à-dire de ne pas les emballer entre guillemets. Alors:

 [{"id":"42","firstname":"Sarah","lastname":"Dilby","age":"40","cars":"Yaris"},
  {"firstname":"Jason","lastname":"Diry","age":"5","id":"5"},
  {"id":"6","firstname":"Bilson","lastname":"Berby","age":"1","cars":"Tipo"}]

devient:

[{"id":42,"firstname":"Sarah","lastname":"Dilby","age":40,"cars":"Yaris"},
 {"firstname":"Jason","lastname":"Diry","age":5,"id":5},
 {"id":6,"firstname":"Bilson","lastname":"Berby","age":1,"cars":"Tipo"}]

Je suppose que la solution de SergL est bonne s’il n’est pas possible de corriger le format des données JSON.

Pour ajouter à cela, le problème dans mon cas spécifique concerne la fonction json_encode de PHP côté serveur. Par défaut, les nombres sont traités comme des chaînes. Pour résoudre ce problème, j'ai dû ajouter l'option JSON_NUMERIC_CHECK à la méthode d'encodage dans le script PHP:

json_encode($assoc_array,JSON_NUMERIC_CHECK);
50
dewd

Vous n'êtes pas obligé de modifier votre JSON. Vous pouvez passer une fonction à orderBy filtrer comme ceci:

$scope.sorterFunc = function(person){
    return parseInt(person.id);
};

<tr ng-repeat="person in people | orderBy:sorterFunc ">
        <td>{{person.id | number}}</td>
        <td>{{person.firstname}} </td>
        <td>{{person.lastname}} </td>
        <td>{{person.age | number}}</td>
        <td>{{person.cars}} </td>
 </tr>
28
Ragnar

Dans votre directive ng-repeat, vous utilisez un filtre de nombre

<td>{{person.id | number}}</td>

Les filtres sont utilisés pour formater la sortie, mais ils ne mettent pas à jour les propriétés du modèle. Par exemple: person.id = 1234.56789 sera rendu sous la forme 1 234,568.

Comme mentionné ci-dessus, vous devez convertir age en type Number. Alors orderBy fonctionnera comme il se doit . Par exemple, dans votre service:

angular.forEach(People.details, function (detail) {
  detail.age = parseFloat(detail.age);
});
15
SergeL

Si votre valeur orderBy n'est pas une variable pointant vers une autre chaîne mais plutôt l'attribut selon lequel vous allez trier, vous devez la mettre entre guillemets.

person in people | orderBy:'-id'

Si, après avoir analysé votre int ou float et que vous ne triez toujours pas correctement, c'est peut-être pour cette raison. <:/(c'est mon bonnet d'âne)

5
Ktel

J'ai rencontré le même problème lorsque je travaillais avec un champ de texte et ngModel pour modifier la valeur du modèle que je commandais. Parce que la valeur était considérée comme une chaîne.

Avec le nouveau code HTML5 <input type="number" /> , Angular analyse la valeur du champ de saisie en un nombre (float, je pense), ce qui m'a aidé à obtenir le bon ordre.

3
naitsirch

Laissez orderBy pointer sur une méthode appartenant à la portée ou à ses ancêtres non isolés et laissez cette méthode renvoyer un nombre renvoyé de la chaîne . Vous devrez peut-être écrire une directive héritant de la portée person créée par les instances de ngRepeat .. à ajouter. cette méthode.

De plus, dans votre cas, l’âge est une chaîne où il aurait pu s’agir d’un nombre entier et le tri numérique s’appliquerait donc de manière native.

Si vous ne pouvez pas modifier le serveur de données, modifiez-le du côté client lors de la récupération.

0
lib3d