39 votes

Orderby ne fonctionne pas avec la syntaxe dict sur ng-repeat

J'essaie d'utiliser ng-repeat avec une syntaxe de style dictionnaire et d'appliquer un ordre à la valeur de clé.

(key, value) in something | orderBy:'key'

Il semble que OrderBy ne fonctionne pas comme prévu

Exemple ici http://jsfiddle.net/mhXuW/

19voto

Mark Rajcok Points 85912

Les paramètres de orderBy doit correspondre à des noms de propriété dans un tableau d'objets.

Vos besoins en matière de données à ressembler à quelque chose comme ceci:

$scope.list2 = [ { id:"2013-01-08T00:00:00", name:'Joe'},
                 { id:"2013-01-09T00:00:00", name:'Sue'}];

Un filtre de ce genre de travail:

<div ng-repeat="item in list2 | orderBy:'id':true">

Le violon.

Notez que orderBy travaille sur l'ensemble de la matrice (something dans votre exemple de code ci-dessus) et qui retourne un tableau trié. orderBy ne sais rien à propos de key et value.

11voto

akonsu Points 9020

ceci n'est pas implémenté. s'il vous plaît voir ici:

https://github.com/angular/angular.js/issues/1286

EDIT (27 août 2013): ce problème semble être résolu maintenant.

6voto

pariesz Points 401

J'ai créé un filtre personnalisé pour rendre cela possible pour une liste de sélection:

 .filter('toDictionaryArray', function () {
    return function (obj) {
        if (!(obj instanceof Object)) return obj;

        var arr = [];
        for (var key in obj) {
            arr.push({ key: key, value: obj[key] });
        }
        return arr;
    }
})
 

la liste de sélection ng-options se lit alors comme suit:

 <select ng-options="kv.key as kv.value for kv in p.options | toDictionaryArray | orderBy:'value'"></select>
 

2voto

Dunc Points 4360

Comme akonsu dit, la fonctionnalité a été demandé ici. Cependant, je ne pouvais pas le faire fonctionner avec la dernière version (1.3.0) bêta.

Il y a une belle solution de contournement enterré dans les commentaires (à noter qu'il nécessite de soulignement, et vous aurez à remplacer les références à la "clef" avec " valeur.$la clé' dans l'exemple ci-dessus):

[Ajouter un filtre]:

app.filter('toArray', function() { return function(obj) {
    if (!(obj instanceof Object)) return obj;
    return _.map(obj, function(val, key) {
        return Object.defineProperty(val, '$key', {__proto__: null, value: key});
    });
}});

Exemple de syntaxe:

<div ng-repeat="val in object | toArray | orderBy:'priority' | filter:fieldSearch">
  {{val.$key}} : {{val}} 
</div>

Inconvénients potentiels:

  • Objet.defineProperty ne fonctionnera pas comme cela dans IE8 (si vous n'avez pas l'esprit de prise de $key énumérable puis c'est facile à changer).
  • Si vos valeurs de propriété ne sont pas des objets, alors vous ne pouvez pas définir l' $de propriété de la clé et cela échoue.
  • Il n'est pas directement intégré dans orderBy ou ngRepeat donc la syntaxe est différente.

2voto

joseym Points 625

Voici un bon travail autour ( angular-toArrayFilter ):

 .filter('toArray', function () {
  return function (obj, addKey) {
    if ( addKey === false ) {
      return Object.keys(obj).map(function(key) {
        return obj[key];
      });
    } else {
      return Object.keys(obj).map(function (key) {
        if(typeof obj[key] == 'object') return Object.defineProperty(obj[key], '$key', {     enumerable: false, value: key});
      });
    }
  };
});
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X