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.