web-dev-qa-db-fra.com

Comment trier la source de données objet dans ng-repeat dans AngularJS?

Supposons que j'ai les utilisateurs suivants:

$scope.users = {
  "2": {
    email: '[email protected]',
    name: 'John'
  },
  "3": {
    email: '[email protected]',
    name: 'Elisa'
  }
}

J'aimerais créer un <select> avec les options suivantes:

<option value="3">Elisa</option>
<option value="2">John</option>

En d'autres termes, les utilisateurs doivent être triés par nom.

J'ai essayé ce qui suit en utilisant la syntaxe (key, value) in expression , mais cela ne fonctionne pas:

<option ng-repeat="(user_id, user) in users | orderBy:'user.name'" 
        value="{{ user.id }}">
  {{ user.name }}
</option>

Exemple en direct ici.

Qu'est-ce que je rate?

Veuillez ne pas suggérer de solutions avec ng-options car j'utilise ui-select2 qui est incompatible avec ng-options.

47
Misha Moroshko

Tandis que vous verriez ceci dans le fil de discussion, la réponse de l'auteur fait référence à un lien, j'ai pensé qu'il serait bien de mettre en place l'une des solutions de contournement mentionnées sur SO:

Il est vrai que cela n’est pas techniquement implémenté, mais il est facile de contourner le problème si vous souhaitez modifier légèrement votre modèle de données: utilisez un filtre personnalisé pour générer un tableau des propriétés de l’objet (sans remplacement]. Si vous ajoutez le champ clé aux objets ("id" dans le cas ci-dessus), vous devriez pouvoir obtenir le comportement que vous recherchez:

app.filter("toArray", function(){
    return function(obj) {
        var result = [];
        angular.forEach(obj, function(val, key) {
            result.Push(val);
        });
        return result;
    };
});
...

$scope.users = {
    1: {name: "John", email: "[email protected]", id: 1},
    2: {name: "Elisa", email: "[email protected]", id: 2}
};

Voici la directive ng-repeat qui pourrait être utilisée:

<option value="{{user.id}}" ng-repeat="user in users | toArray | orderBy:'name'">{{user.name}}</option>

Et voici le plunkr .

Notez que le filtre orderBy prend name comme paramètre et non user.name.

Malheureusement, l'ajout de la propriété id à vos objets crée un risque d'incompatibilité avec sa clé dans l'objet contenant. 

Dans le lien que vous avez mentionné dans votre réponse, il existe également des solutions proposées qui créent la propriété id dans les objets utilisateur à la volée, mais je pense que cette approche est un peu moins compliquée (au prix de la réplication).

54
mhess

OK, j'ai trouvé la réponse: 

Il n'est pas encore implémenté :(

9
Misha Moroshko

En plus de la réponse acceptée et du format de vos données, vous devez transformer vos données en tant que

app.filter('myFilterUsers',function(){
    return function(data)
    {
        var newRes = [];
        angular.forEach(data,function(val,key){
            val["id"] = key;  //Add the ID in the JSON object as you need this as well.
            newRes.Push(val);
        });
        return newRes;
    }
});
0
Saksham