Comment appeler un tube angulaire 2 avec plusieurs arguments?

205

Je sais que je peux appeler un tuyau comme ça:

{{ myData | date:'fullDate' }}

Ici, le canal de date ne prend qu'un seul argument. Quelle est la syntaxe pour appeler un canal avec plus de paramètres, à partir du modèle HTML du composant et directement dans le code?

Eran Shabi
la source

Réponses:

405

Dans le modèle de votre composant, vous pouvez utiliser plusieurs arguments en les séparant par des deux-points:

{{ myData | myPipe: 'arg1':'arg2':'arg3'... }}

À partir de votre code, cela ressemblera à ceci:

new MyPipe().transform(myData, arg1, arg2, arg3)

Et dans votre fonction de transformation à l'intérieur de votre pipe, vous pouvez utiliser les arguments comme ceci:

export class MyPipe implements PipeTransform { 
    // specify every argument individually   
    transform(value: any, arg1: any, arg2: any, arg3: any): any { }
    // or use a rest parameter
    transform(value: any, ...args: any[]): any { }
}

Bêta 16 et versions antérieures (26/04/2016)

Les tuyaux prennent un tableau qui contient tous les arguments, vous devez donc les appeler comme ceci:

new MyPipe().transform(myData, [arg1, arg2, arg3...])

Et votre fonction de transformation ressemblera à ceci:

export class MyPipe implements PipeTransform {    
    transform(value:any, args:any[]):any {
        var arg1 = args[0];
        var arg2 = args[1];
        ...
    }
}
Eran Shabi
la source
8
Cette conception est idiote. Je dois vérifier le document chaque fois que je rencontre ce problème
tom10271
À quoi ressemblerait le bit de modèle si arg1et arg2où les deux facultatifs et vous vouliez seulement passer arg2?
freethebees
si vous passez undefinedcomme premier argument, il obtiendra sa valeur par défaut.
Eran Shabi
3
de nos jours au lieu d' transform(value:any, arg1:any, arg2:any, arg3:any)utiliser l'opérateur de repos se sent mieux je pense:transform(value:any, ...args:any[])
mkb
pourquoi transform (... args) provoque une erreur, mais transform (value, ... args) pas?
Sh eldeeb
45

Vous manquez le vrai tuyau.

{{ myData | date:'fullDate' }}

Plusieurs paramètres peuvent être séparés par deux points (:).

{{ myData | myPipe:'arg1':'arg2':'arg3' }}

Vous pouvez également chaîner des tuyaux, comme ceci:

{{ myData | date:'fullDate' | myPipe:'arg1':'arg2':'arg3' }}
Eugène
la source
25

Depuis la version beta.16, les paramètres ne sont plus transmis en tant que tableau à la transform()méthode mais plutôt en tant que paramètres individuels:

{{ myData | date:'fullDate':'arg1':'arg2' }}


export class DatePipe implements PipeTransform {    
  transform(value:any, arg1:any, arg2:any):any {
        ...
}

https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta16-2016-04-26

les canaux prennent désormais un nombre variable d'arguments, et non un tableau contenant tous les arguments.

Günter Zöchbauer
la source
À quoi ressemblerait le bit de modèle si arg1et arg2où les deux facultatifs et vous vouliez seulement passer arg2?
freethebees
Pouvons-nous utiliser des noms de variable différents autres que arg1? Comme isFullDate. Je demande juste parce que chaque exemple utilise cela.
sabithpocker
'arg1'et ne 'arg2'sont que des littéraux de chaîne passés en tant que paramètres supplémentaires au tuyau. Vous pouvez utiliser n'importe quelle valeur ou référence disponible dans cette étendue (l'instance de composant actuelle)
Günter Zöchbauer
1
@freethebees vous devez passer null
karoluS
la méthode de transformation ne prend pas en charge les arguments de tableau bon point @Gunter
BALS
5

J'utilise Pipes dans Angular 2+ pour filtrer les tableaux d'objets. Ce qui suit prend plusieurs arguments de filtre, mais vous pouvez n'en envoyer qu'un si cela convient à vos besoins. Voici un exemple StackBlitz . Il trouvera les clés que vous souhaitez filtrer, puis les filtres selon la valeur que vous fournissez. C'est en fait assez simple, si cela semble compliqué, ce n'est pas le cas, consultez l' exemple StackBlitz .

Voici le tuyau appelé dans une directive * ngFor,

<div *ngFor='let item of items | filtermulti: [{title:"mr"},{last:"jacobs"}]' >
  Hello {{item.first}} !
</div>

Voici le Pipe,

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

@Pipe({
  name: 'filtermulti'
})
export class FiltermultiPipe implements PipeTransform {
  transform(myobjects: Array<object>, args?: Array<object>): any {
    if (args && Array.isArray(myobjects)) {
      // copy all objects of original array into new array of objects
      var returnobjects = myobjects;
      // args are the compare oprators provided in the *ngFor directive
      args.forEach(function (filterobj) {
        let filterkey = Object.keys(filterobj)[0];
        let filtervalue = filterobj[filterkey];
        myobjects.forEach(function (objectToFilter) {
          if (objectToFilter[filterkey] != filtervalue && filtervalue != "") {
            // object didn't match a filter value so remove it from array via filter
            returnobjects = returnobjects.filter(obj => obj !== objectToFilter);
          }
        })
      });
      // return new array of objects to *ngFor directive
      return returnobjects;
    }
  }
}

Et voici le composant contenant l'objet à filtrer,

import { Component } from '@angular/core';
import { FiltermultiPipe } from './pipes/filtermulti.pipe';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';
  items = [{ title: "mr", first: "john", last: "jones" }
   ,{ title: "mr", first: "adrian", last: "jacobs" }
   ,{ title: "mr", first: "lou", last: "jones" }
   ,{ title: "ms", first: "linda", last: "hamilton" }
  ];
}

Exemple StackBlitz

Exemple GitHub: créez une copie de travail de cet exemple ici

*Notez s'il vous plaît que dans une réponse fournie par Gunter, Gunter déclare que les tableaux ne sont plus utilisés comme interfaces de filtrage, mais j'ai recherché le lien qu'il fournit et je n'ai rien trouvé qui réponde à cette affirmation. De plus, l'exemple StackBlitz fourni montre que ce code fonctionne comme prévu dans Angular 6.1.9. Cela fonctionnera dans Angular 2+.

Codage heureux :-)

user3777549
la source
Il ne sert à rien de passer un seul tableau avec plusieurs entrées au lieu de passer plusieurs paramètres directement au tuyau.
BrunoJCM
Le tableau contient des objets. Les objets peuvent contenir plusieurs paires de valeurs clés utilisées pour créer des requêtes dynamiques dans lesquelles vous pouvez rechercher des enregistrements correspondants à l'aide des noms de colonne par rapport aux valeurs de ligne de la colonne. Vous n'obtiendrez pas ce niveau d'interrogation dynamique en passant des paramètres CSV.
user3777549
-2

Étendu depuis: user3777549

Filtre à valeurs multiples sur un ensemble de données (référence à la clé de titre uniquement)

HTML

<div *ngFor='let item of items | filtermulti: [{title:["mr","ms"]},{first:["john"]}]' >
 Hello {{item.first}} !
</div>

filterMultiple

args.forEach(function (filterobj) {
    console.log(filterobj)
    let filterkey = Object.keys(filterobj)[0];
    let filtervalue = filterobj[filterkey];
    myobjects.forEach(function (objectToFilter) {

      if (!filtervalue.some(x=>x==objectToFilter[filterkey]) && filtervalue != "") {
        // object didn't match a filter value so remove it from array via filter
        returnobjects = returnobjects.filter(obj => obj !== objectToFilter);
      }
    })
  });
Sharan
la source