web-dev-qa-db-fra.com

Trier un tableau d'objets dans Angular2

J'ai des problèmes avec le tri d'un tableau d'objet dans Angular2.

L'objet ressemble à:

[
  {
    "name": "t10",
    "ts": 1476778297100,
    "value": "32.339264",
    "xid": "DP_049908"
  },
  {
    "name": "t17",
    "ts": 1476778341100,
    "value": "true",
    "xid": "DP_693259"
  },
  {
    "name": "t16",
    "ts": 1476778341100,
    "value": "true",
    "xid": "DP_891890"
  }
]

Et est stocké dans la variable values.

Tout ce que je veux, c'est que la boucle *ngFor La trie par la propriété name.

<table *ngIf="values.length">
    <tr *ngFor="let elem of values">
      <td>{{ elem.name }}</td>
      <td>{{ elem.ts }}</td>
      <td>{{ elem.value }}</td>
    </tr>
</table>

J'ai essayé de le faire avec des tuyaux, mais j'ai échoué lamentablement. Toute aide appréciée.

Lien Plunker : https://plnkr.co/edit/e9laTBnqJKb8VzhHEBmn?p=preview

Modifier

Ma pipe:

import {Component, Inject, OnInit, Pipe, PipeTransform} from '@angular/core';

@Component({
  selector: 'watchlist',
  templateUrl: './watchlist.component.html',
  styleUrls: ['./watchlist.component.css'],
  pipes: [ ArraySortPipe ]
})
@Pipe({
  name: "sort"
})

export class ArraySortPipe implements PipeTransform {
  transform(array: Array<string>, args: string): Array<string> {
    array.sort((a: any, b: any) => {
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }
}

Et mettez simplement le nom pipe dans un fichier html:

<tr *ngFor="let elem of values | sort">
23
user7209780

Bien que vous puissiez résoudre ce problème avec un tuyau, vous devez vous demander si la possibilité de réutiliser un tuyau vous est utile dans votre projet particulier. Aurez-vous souvent besoin de trier des objets à l'aide de la clé "name" sur d'autres tableaux ou d'autres composants à l'avenir? Ces données changeront-elles assez souvent et de manière à rendre difficile le simple tri dans la composante? Aurez-vous besoin que le tableau soit trié en cas de modification de la vue ou des entrées?

J'ai créé un disque modifié dans lequel le tableau est trié dans le constructeur du composant, mais rien n'empêche que cette fonctionnalité ne puisse pas être déplacée dans sa propre méthode (sortValuesArray par exemple) pour pouvoir être réutilisée si nécessaire.

constructor() {
  this.values.sort((a, b) => {
    if (a.name < b.name) return -1;
    else if (a.name > b.name) return 1;
    else return 0;
  });
}

Edité Plunker

22
peterhuettl

Essaye ça

Trier de A à la fin de l'alphabet:

this.suppliers.sort((a,b)=>a.SupplierName.localeCompare(b.SupplierName));

Z => A (ordre inverse)

this.suppliers.sort((a,b)=>b.SupplierName.localeCompare(a.SupplierName));
17
suphi

Votre pipe attend des chaînes mais il obtient des objets, vous devez l’adapter:

export class ArraySortPipe implements PipeTransform {
  transform(array: Array<any>): Array<string> {
    array.sort((a: any, b: any) => {
      if (a.name < b.name) {
        return -1;
      } else if (a.name > b.name) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }
}
13
Meir

Angular conseille néanmoins de ne pas utiliser de tuyaux pour le tri et le filtrage, comme dans AngularJs.

Cela va ralentir votre application, avoir des problèmes de performances. Il est bien préférable d’indiquer votre tri dans votre composant avant de le transmettre au modèle.

La raison est expliquée sur https://angular.io/guide/pipes#no-filter-pipe

Si vous travaillez avec une présentation de composant structuré Nice, vous pouvez le faire même sur le configurateur:

 @Input()
  set users(users: Array<User>) {
    this.usersResult = (users || []).sort((a: User, b: User) => a.name < b.name ? -1 : 1)
  }
8
Bo Vandersteene

Ceci est adaptable à un tel cas d'utilisation.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'sortBy'
})
export class SortByPipe implements PipeTransform {
  transform(arr: Array<any>, prop: any, reverse: boolean = false): any {
    if (arr === undefined) return
    const m = reverse ? -1 : 1
    return arr.sort((a: any, b: any): number => {
      const x = a[prop]
      const y = b[prop]
      return (x === y) ? 0 : (x < y) ? -1*m : 1*m
    })
  }
}

Usage:-
<div *ngFor="let item of list | sortBy: 'isDir': true">

[~ # ~] met à jour [~ # ~]
Reportez-vous à Bo's answer, le filtrage et le tri dans les tuyaux n'étant pas recommandé.

3
Vikas Gautam