web-dev-qa-db-fra.com

angular 2 trier et filtrer

Dans Angularjs 1, il est possible de trier et filtrer de la manière suivante:

<ul ng-repeat="friend in friends | filter:query | orderBy: 'name' ">
   <li>{{friend.name}}</li>
</ul>

Mais je n’ai trouvé aucun exemple de la façon de procéder dans Angularjs 2.0. Ma question est de savoir comment trier et filtrer dans Angularjs 2.0? S'il n'est toujours pas pris en charge, est-ce que quelqu'un sait à quel moment et s'il sera intégré à Angularjs 2.0?

72
alexsoftware

Ceci n’a pas été ajouté dès le départ car l’équipe Angular veut que Angular 2 soit réduite. OrderBy ne tient pas compte de la réflexion qui rompt avec la minification. Départ réponse de Miško Heverey à ce sujet.

J'ai pris le temps de créer un canal OrderBy prenant en charge les tableaux à une ou plusieurs dimensions. Il prend également en charge la possibilité de trier sur plusieurs colonnes du tableau multidimensionnel.

<li *ngFor="let person of people | orderBy : ['-lastName', 'age']">{{person.firstName}} {{person.lastName}}, {{person.age}}</li>

Ce canal permet d’ajouter d’autres éléments au tableau après le rendu de la page et de trier les tableaux avec les nouveaux éléments correctement.

J'ai un écrire sur le processus ici .

Et voici une démo de travail: http://fuelinteractive.github.io/fuel-ui/#/pipe/orderby et https://plnkr.co/edit/DHLVc0?p = info

EDIT: Ajout d'une nouvelle démo à http://fuelinteractive.github.io/fuel-ui/#/pipe/orderby

EDIT 2: Mise à jour de ngFor vers une nouvelle syntaxe

79
Cory Shaw

Voici un filtre simple pour un tableau d'objets contenant des attributs avec des valeurs de chaîne (ES6)

filter-array-pipe.js

import {Pipe} from 'angular2/core';

// # Filter Array of Objects
@Pipe({ name: 'filter' })
export class FilterArrayPipe {
  transform(value, args) {
    if (!args[0]) {
      return value;
    } else if (value) {
      return value.filter(item => {
        for (let key in item) {
          if ((typeof item[key] === 'string' || item[key] instanceof String) && 
              (item[key].indexOf(args[0]) !== -1)) {
            return true;
          }
        }
      });
    }
  }
}

Votre composant

myobjComponent.js

import {Component} from 'angular2/core';
import {HTTP_PROVIDERS, Http} from 'angular2/http';
import {FilterArrayPipe} from 'filter-array-pipe';

@Component({
  templateUrl: 'myobj.list.html',
  providers: [HTTP_PROVIDERS],
  pipes: [FilterArrayPipe]
})
export class MyObjList {
  static get parameters() {
    return [[Http]];
  }
  constructor(_http) {
    _http.get('/api/myobj')
      .map(res => res.json())
      .subscribe(
        data => this.myobjs = data,
        err => this.logError(err))
      );
  }
  resetQuery(){
    this.query = '';
  }
}

Dans votre template

myobj.list.html

<input type="text" [(ngModel)]="query" placeholder="... filter" > 
<div (click)="resetQuery()"> <span class="icon-cross"></span> </div>
</div>
<ul><li *ngFor="#myobj of myobjs| filter:query">...<li></ul>
18
select

Il n'est pas pris en charge par la conception. Le tuyau sortBy peut entraîner de réels problèmes de performances pour une application à l'échelle de production. C'était un problème avec angular version 1.

Vous ne devez pas créer de fonction de tri personnalisée. Au lieu de cela, vous devez d'abord trier votre tableau dans le fichier TypeScript, puis l'afficher. Si la commande doit être mise à jour lorsque, par exemple, une liste déroulante est sélectionnée, cette sélection doit déclencher une fonction et appeler votre fonction de tri appelée à partir de celle-ci. Cette fonction de tri peut être extraite vers un service afin qu'il puisse être réutilisé. De cette façon, le tri ne sera appliqué que si cela est nécessaire et les performances de votre application seront bien meilleures.

18
trees_are_great

Un canal prend des données en entrée et les transforme en une sortie souhaitée. Ajoutez ce fichier de canal: orderby.ts dans votre dossier /app.

orderby.ts

//The pipe class implements the PipeTransform interface's transform method that accepts an input value and an optional array of parameters and returns the transformed value.

import { Pipe,PipeTransform } from "angular2/core";

//We tell Angular that this is a pipe by applying the @Pipe decorator which we import from the core Angular library.

@Pipe({

  //The @Pipe decorator takes an object with a name property whose value is the pipe name that we'll use within a template expression. It must be a valid JavaScript identifier. Our pipe's name is orderby.

  name: "orderby"
})

export class OrderByPipe implements PipeTransform {
  transform(array:Array<any>, args?) {

    // Check if array exists, in this case array contains articles and args is an array that has 1 element : !id

    if(array) {

      // get the first element

      let orderByValue = args[0]
      let byVal = 1

      // check if exclamation point 

      if(orderByValue.charAt(0) == "!") {

        // reverse the array

        byVal = -1
        orderByValue = orderByValue.substring(1)
      }
      console.log("byVal",byVal);
      console.log("orderByValue",orderByValue);

      array.sort((a: any, b: any) => {
        if(a[orderByValue] < b[orderByValue]) {
          return -1*byVal;
        } else if (a[orderByValue] > b[orderByValue]) {
          return 1*byVal;
        } else {
          return 0;
        }
      });
      return array;
    }
    //
  }
}

Dans votre fichier de composant (app.component.ts), importez le canal que vous venez d'ajouter à l'aide de: import {OrderByPipe} from './orderby';

Ajoutez ensuite *ngFor="#article of articles | orderby:'id'" à l'intérieur de votre modèle si vous souhaitez trier vos articles par ID en ordre croissant ou par orderby:'!id'" par ordre décroissant.

Nous ajoutons des paramètres à une conduite en suivant le nom de la conduite avec un signe deux-points (:), puis la valeur du paramètre

Nous devons répertorier nos tuyaux dans la matrice de tuyaux du décorateur @Component. pipes: [ OrderByPipe ].

app.component.ts

import {Component, OnInit} from 'angular2/core';
import {OrderByPipe} from './orderby';

@Component({
    selector: 'my-app',
    template: `
      <h2>orderby-pipe by N2B</h2>
      <p *ngFor="#article of articles | orderby:'id'">
        Article title : {{article.title}}
      </p>
    `,
    pipes: [ OrderByPipe ]

})
export class AppComponent{
    articles:Array<any>
    ngOnInit(){
        this.articles = [
        {
            id: 1,
            title: "title1"
        },{
            id: 2,
            title: "title2",
        }]  
    }

}

Plus d'infos ici sur mon github et ce post sur mon site

13
Nicolas2bert

Vous devez créer votre propre tuyau pour le tri des tableaux. En voici un exemple.

<li *ngFor="#item of array | arraySort:'-date'">{{item.name}} {{item.date | date:'medium' }}</li>

https://plnkr.co/edit/DU6pxr?p=preview

4
Vlado Tesanovic

Ceci est mon genre. Il fera le tri numérique, le tri par chaîne et le tri par date.

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

@Pipe({
  name: 'sortPipe'
 })

export class SortPipe implements PipeTransform {

    transform(array: Array<string>, key: string): Array<string> {

        console.log("Entered in pipe*******  "+ key);


        if(key === undefined || key == '' ){
            return array;
        }

        var arr = key.split("-");
        var keyString = arr[0];   // string or column name to sort(name or age or date)
        var sortOrder = arr[1];   // asc or desc order
        var byVal = 1;


        array.sort((a: any, b: any) => {

            if(keyString === 'date' ){

                let left    = Number(new Date(a[keyString]));
                let right   = Number(new Date(b[keyString]));

                return (sortOrder === "asc") ? right - left : left - right;
            }
            else if(keyString === 'name'){

                if(a[keyString] < b[keyString]) {
                    return (sortOrder === "asc" ) ? -1*byVal : 1*byVal;
                } else if (a[keyString] > b[keyString]) {
                    return (sortOrder === "asc" ) ? 1*byVal : -1*byVal;
                } else {
                    return 0;
                }  
            }
            else if(keyString === 'age'){
                return (sortOrder === "asc") ? a[keyString] - b[keyString] : b[keyString] - a[keyString];
            }

        });

        return array;

  }

}
1
Human Being