Come posso chiamare una pipe Angular 2 con più argomenti?


205

So di poter chiamare una pipe come questa:

{{ myData | date:'fullDate' }}

Qui la pipe della data accetta solo un argomento. Qual è la sintassi per chiamare una pipe con più parametri, dal modello HTML del componente e direttamente nel codice?

Risposte:


405

Nel modello del componente è possibile utilizzare più argomenti separandoli con due punti:

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

Dal tuo codice sarà simile a questo:

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

E nella tua funzione di trasformazione all'interno della tua pipe puoi usare gli argomenti come questo:

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 { }
}

Beta 16 e precedenti (26-04-2016)

I pipe accettano un array che contiene tutti gli argomenti, quindi è necessario chiamarli in questo modo:

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

E la tua funzione di trasformazione sarà simile a questa:

export class MyPipe implements PipeTransform {    
    transform(value:any, args:any[]):any {
        var arg1 = args[0];
        var arg2 = args[1];
        ...
    }
}

8
Questo design è stupido. Devo controllare il documento ogni volta che mi imbatto in questo problema
tom10271,

Come sarebbe il bit del modello se arg1e arg2dove sia facoltativo che tu volessi solo passare arg2?
Freethebees,

se passi undefinedcome primo argomento otterrà il suo valore predefinito.
Eran Shabi,

3
oggi invece di transform(value:any, arg1:any, arg2:any, arg3:any)usare l'operatore di riposo mi sento meglio penso:transform(value:any, ...args:any[])
MK

perché transform (... args) causa un errore, ma transform (value, ... args) no?
Sh eldeeb,

45

Ti stai perdendo la pipa vera e propria.

{{ myData | date:'fullDate' }}

Più parametri possono essere separati da due punti (:).

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

Inoltre puoi incatenare i tubi, in questo modo:

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

25

Da beta.16 i parametri non vengono più passati come array al transform()metodo ma come singoli parametri:

{{ 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

le pipe ora accettano un numero variabile di argomenti e non una matrice che contiene tutti gli argomenti.


Come sarebbe il bit del modello se arg1e arg2dove sia facoltativo che tu volessi solo passare arg2?
Freethebees,

Possiamo usare nomi di variabili diversi da arg1? Come isFullDate. Sto solo chiedendo perché ogni esempio usa questo.
sabithpocker,

'arg1'e 'arg2'sono solo letterali stringa passati come parametri aggiuntivi alla pipe. Puoi utilizzare qualsiasi valore o riferimento disponibile in tale ambito (l'istanza del componente corrente)
Günter Zöchbauer

1
@freethebees devi passare null
karoluS

metodo transform non supporta args buon punto @Gunter
BALS

5

Uso Pipes in Angular 2+ per filtrare array di oggetti. Quanto segue accetta più argomenti di filtro, ma è possibile inviarne solo uno se soddisfa le proprie esigenze. Ecco un esempio StackBlitz . Troverà le chiavi in ​​base alle quali filtrare, quindi i filtri in base al valore fornito. In realtà è abbastanza semplice, se sembra complicato non lo è, dai un'occhiata all'esempio StackBlitz .

Ecco il Pipe chiamato in una direttiva * ngPer,

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

Ecco la pipa,

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;
    }
  }
}

Ed ecco il componente che contiene l'oggetto da filtrare,

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" }
  ];
}

StackBlitz Esempio

Esempio GitHub: fork una copia di lavoro di questo esempio qui

*Notare che che in una risposta fornita da Gunter, Gunter afferma che le matrici non vengono più utilizzate come interfacce di filtro, ma ho cercato il link che fornisce e non ho trovato nulla che parla di tale affermazione. Inoltre, l'esempio StackBlitz fornito mostra che questo codice funziona come previsto in Angular 6.1.9. Funzionerà in Angular 2+.

Happy Coding :-)


Non ha senso passare un singolo array con più voci invece di passare parametri multipli direttamente al pipe.
BrunoJCM,

La matrice contiene oggetti. Gli oggetti possono contenere più coppie di valori chiave utilizzate per creare query dinamiche in cui è possibile cercare record corrispondenti utilizzando i nomi di colonna rispetto ai valori di riga della colonna. Non otterresti questo livello di query dinamica passando parametri CSV.
user3777549

-2

Esteso da: user3777549

Filtro multi-valore su un set di dati (solo riferimento alla chiave del titolo)

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);
      }
    })
  });
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.