Jak wywołać potok Angular 2 z wieloma argumentami?

204

Wiem, że mogę nazwać taką potokiem:

{{ myData | date:'fullDate' }}

Tutaj potok daty ma tylko jeden argument. Jaka jest składnia wywoływania potoku z większą liczbą parametrów, z szablonu HTML komponentu i bezpośrednio w kodzie?

Eran Shabi
źródło

Odpowiedzi:

404

W szablonie komponentu możesz użyć wielu argumentów, oddzielając je dwukropkami:

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

Z twojego kodu będzie to wyglądać tak:

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

A w funkcji transformacji w potoku możesz użyć następujących argumentów:

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 i wcześniejsze (26.04.2016)

Potoki przyjmują tablicę zawierającą wszystkie argumenty, więc musisz wywołać je w następujący sposób:

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

Twoja funkcja przekształcenia będzie wyglądać następująco:

export class MyPipe implements PipeTransform {    
    transform(value:any, args:any[]):any {
        var arg1 = args[0];
        var arg2 = args[1];
        ...
    }
}
Eran Shabi
źródło
8
Ten projekt jest głupiutki. Muszę sprawdzać dokument za każdym razem, gdy napotykam ten problem
tom10271,
Jak wyglądałby bit szablonu, gdyby arg1i arg2gdzie oba były opcjonalne i chciałeś tylko przekazać arg2?
freethebees
jeśli podasz undefinedjako pierwszy argument, uzyska domyślną wartość.
Eran Shabi,
3
obecnie zamiast transform(value:any, arg1:any, arg2:any, arg3:any)korzystać z operatora reszty, wydaje mi się, że lepiej:transform(value:any, ...args:any[])
mkb
dlaczego transformacja (... argumenty) powoduje błąd, a transformacja (wartość, ... argumenty) nie?
Sh eldeeb
45

Brakuje rzeczywistej rury.

{{ myData | date:'fullDate' }}

Wiele parametrów można oddzielić dwukropkiem (:).

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

Możesz także łączyć rury, takie jak:

{{ myData | date:'fullDate' | myPipe:'arg1':'arg2':'arg3' }}
Eugene
źródło
25

Od wersji beta.16 parametry nie są już przekazywane do tablicy jako transform()metoda, ale jako indywidualne parametry:

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

potoki przyjmują teraz zmienną liczbę argumentów, a nie tablicę zawierającą wszystkie argumenty.

Günter Zöchbauer
źródło
Jak wyglądałby bit szablonu, gdyby arg1i arg2gdzie oba były opcjonalne i chciałeś tylko przekazać arg2?
freethebees
Czy możemy używać innych nazw zmiennych niż arg1? Jak isFullDate. Pytam tylko, ponieważ każdy przykład tego używa.
sabithpocker
'arg1'i 'arg2'są po prostu literałami ciągów przekazywanymi jako dodatkowe parametry do potoku. Możesz użyć dowolnej wartości lub odwołania dostępnego w tym zakresie (bieżąca instancja komponentu)
Günter Zöchbauer
1
@freethebees musisz przekazać zero
karoluS
metoda transformacji nie obsługuje argumentów tablicowych dobry punkt @Gunter
BALS
5

Używam rur w Angular 2+ do filtrowania tablic obiektów. Poniżej podano wiele argumentów filtru, ale możesz wysłać tylko jeden, jeśli odpowiada to Twoim potrzebom. Oto przykład StackBlitz . Znajduje klucze, które chcesz filtrować, a następnie filtruje według podanej wartości. To właściwie dość proste, jeśli wydaje się skomplikowane, nie jest, sprawdź przykład StackBlitz .

Oto rura wywoływana w dyrektywie * ngFor,

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

Oto fajka,

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

A tutaj jest komponent zawierający obiekt do filtrowania,

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

Przykład StackBlitz

Przykład GitHub: rozwidlaj roboczą kopię tego przykładu tutaj

* Należy pamiętać, że w odpowiedzi udzielonej przez Guntera Gunter stwierdza, że ​​tablice nie są już używane jako interfejsy filtrów, ale przeszukałem podany przez niego link i nie znalazłem nic, co przemawiałoby za tym twierdzeniem. Również podany przykład StackBlitz pokazuje ten kod działający zgodnie z przeznaczeniem w Angular 6.1.9. Będzie działać w Angular 2+.

Happy Coding :-)

użytkownik3777549
źródło
Nie ma sensu przekazywanie pojedynczej tablicy z wieloma wpisami zamiast przekazywania wielu parametrów bezpośrednio do potoku.
BrunoJCM,
Tablica zawiera obiekty. Obiekty mogą zawierać wiele par wartości klucza używanych do tworzenia zapytań dynamicznych, w których można wyszukiwać pasujące rekordy przy użyciu nazw kolumn w porównaniu z wartościami wierszy kolumny. Nie uzyskałbyś takiego poziomu dynamicznego zapytania, przekazującego parametry CSV.
user3777549,
-2

Rozszerzony od: user3777549

Filtr wielowartościowy w jednym zestawie danych (tylko odniesienie do klucza tytułu)

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
źródło