Wie rufe ich eine Angular 2-Pipe mit mehreren Argumenten auf?

203

Ich weiß, dass ich eine Pfeife wie diese nennen kann:

{{ myData | date:'fullDate' }}

Hier nimmt die Datums-Pipe nur ein Argument an. Wie lautet die Syntax zum Aufrufen einer Pipe mit mehr Parametern aus dem HTML-Code der Komponente und direkt im Code?

Eran Shabi
quelle

Antworten:

403

In der Vorlage Ihrer Komponente können Sie mehrere Argumente verwenden, indem Sie sie durch Doppelpunkte trennen:

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

Aus Ihrem Code sieht es folgendermaßen aus:

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

Und in Ihrer Transformationsfunktion in Ihrer Pipe können Sie die folgenden Argumente verwenden:

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 und früher (26.04.2016)

Pipes verwenden ein Array, das alle Argumente enthält. Sie müssen sie daher folgendermaßen aufrufen:

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

Und Ihre Transformationsfunktion sieht folgendermaßen aus:

export class MyPipe implements PipeTransform {    
    transform(value:any, args:any[]):any {
        var arg1 = args[0];
        var arg2 = args[1];
        ...
    }
}
Eran Shabi
quelle
8
Dieser Entwurf ist dumm. Ich muss das Dokument jedes Mal überprüfen, wenn ich auf dieses Problem
stoße
Wie würde das Vorlagenbit aussehen, wenn arg1und arg2wo beide optional sind und Sie nur weitergeben wollten arg2?
Freethebees
Wenn Sie undefinedals erstes Argument übergeben, erhält es seinen Standardwert.
Eran Shabi
2
heutzutage statt transform(value:any, arg1:any, arg2:any, arg3:any) fühlt es sich besser an, den transform(value:any, ...args:any[])
Restoperator zu verwenden
Warum verursacht transform (... args) einen Fehler, transform (value, ... args) jedoch nicht?
Sh eldeeb
45

Ihnen fehlt die eigentliche Pfeife.

{{ myData | date:'fullDate' }}

Mehrere Parameter können durch einen Doppelpunkt (:) getrennt werden.

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

Sie können auch Rohre wie folgt verketten:

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

Seit Beta.16 werden die Parameter nicht mehr als Array an die transform()Methode übergeben, sondern als einzelne Parameter:

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

Pipes akzeptieren jetzt eine variable Anzahl von Argumenten und kein Array, das alle Argumente enthält.

Günter Zöchbauer
quelle
Wie würde das Vorlagenbit aussehen, wenn arg1und arg2wo beide optional sind und Sie nur weitergeben wollten arg2?
Freethebees
Können wir andere Variablennamen als verwenden arg1? Wie isFullDate. Ich frage nur, weil jedes Beispiel dies verwendet.
Sabithpocker
'arg1'und 'arg2'sind nur String-Literale, die als zusätzliche Parameter an die Pipe übergeben werden. Sie können jeden Wert oder jede Referenz verwenden, die in diesem Bereich verfügbar ist (die aktuelle Komponenteninstanz)
Günter Zöchbauer
1
@freethebees Sie müssen null
karoluS
Transformationsmethode unterstützt Array-Argumente nicht guter Punkt @Gunter
BALS
5

Ich verwende Pipes in Angular 2+, um Arrays von Objekten zu filtern. Im Folgenden werden mehrere Filterargumente verwendet, Sie können jedoch nur eines senden, wenn dies Ihren Anforderungen entspricht. Hier ist ein StackBlitz-Beispiel . Es findet die Schlüssel, nach denen Sie filtern möchten, und filtert dann nach dem von Ihnen angegebenen Wert. Es ist eigentlich ganz einfach. Wenn es kompliziert klingt, sehen Sie sich das StackBlitz-Beispiel an .

Hier ist die Pipe, die in einer * ngFor-Direktive aufgerufen wird.

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

Hier ist die Pfeife,

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

Und hier ist die Komponente, die das zu filternde Objekt enthält:

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 Beispiel

GitHub-Beispiel: Geben Sie hier eine Arbeitskopie dieses Beispiels ein

*Bitte beachten Sie dass Gunter in einer Antwort von Gunter angibt, dass Arrays nicht mehr als Filterschnittstellen verwendet werden, aber ich habe den von ihm bereitgestellten Link durchsucht und nichts gefunden, was zu dieser Behauptung spricht. Das bereitgestellte StackBlitz-Beispiel zeigt auch, dass dieser Code wie in Angular 6.1.9 vorgesehen funktioniert. Es wird in Angular 2+ funktionieren.

Viel Spaß beim Codieren :-)

user3777549
quelle
Es macht keinen Sinn, ein einzelnes Array mit mehreren Einträgen zu übergeben, anstatt mehrere Parameter direkt an die Pipe zu übergeben.
BrunoJCM
Das Array enthält Objekte. Die Objekte können mehrere Schlüsselwertpaare enthalten, mit denen dynamische Abfragen erstellt werden, bei denen Sie anhand von Spaltennamen im Vergleich zu den Zeilenwerten der Spalte nach übereinstimmenden Datensätzen suchen können. Sie würden diese Ebene der dynamischen Abfrage nicht erhalten, wenn Sie CSV-Parameter übergeben würden.
user3777549
-2

Erweitert von: user3777549

Mehrwertfilter für einen Datensatz (nur Verweis auf Titelschlüssel)

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
quelle