¿Cómo llamo una tubería Angular 2 con múltiples argumentos?

205

Sé que puedo llamar a una tubería así:

{{ myData | date:'fullDate' }}

Aquí la tubería de fecha toma solo un argumento. ¿Cuál es la sintaxis para llamar a una tubería con más parámetros, desde la plantilla HTML del componente y directamente en el código?

Eran Shabi
fuente

Respuestas:

405

En la plantilla de su componente puede usar múltiples argumentos separándolos con dos puntos:

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

Desde su código se verá así:

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

Y en su función de transformación dentro de su tubería puede usar los argumentos de esta manera:

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 y anteriores (2016-04-26)

Las tuberías toman una matriz que contiene todos los argumentos, por lo que debe llamarlos así:

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

Y su función de transformación se verá así:

export class MyPipe implements PipeTransform {    
    transform(value:any, args:any[]):any {
        var arg1 = args[0];
        var arg2 = args[1];
        ...
    }
}
Eran Shabi
fuente
8
Este diseño es tonto. Necesito revisar el documento cada vez que me encuentro con este problema
tom10271
¿Cómo sería el bit mirada como si la plantilla arg1y arg2donde ambos opcionales y sólo quería pasar arg2?
freethebees
Si pasa undefinedcomo primer argumento, obtendrá su valor predeterminado.
Eran Shabi
3
hoy en día en lugar de transform(value:any, arg1:any, arg2:any, arg3:any)utilizar el operador de descanso se siente mejor, creo:transform(value:any, ...args:any[])
mkb
¿Por qué transform (... args) causa un error, pero transform (value, ... args) no?
Sh eldeeb
45

Te estás perdiendo la tubería real.

{{ myData | date:'fullDate' }}

Múltiples parámetros pueden estar separados por dos puntos (:).

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

También puede encadenar tuberías, así:

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

Desde beta.16, los parámetros ya no se pasan como matriz al transform()método, sino como parámetros individuales:

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

las tuberías ahora toman un número variable de argumentos, y no una matriz que contiene todos los argumentos.

Günter Zöchbauer
fuente
¿Cómo sería el bit mirada como si la plantilla arg1y arg2donde ambos opcionales y sólo quería pasar arg2?
freethebees
¿Podemos usar diferentes nombres de variables que no sean arg1? Al igual isFullDate. Solo pregunto porque cada ejemplo usa esto.
sabithpocker
'arg1'y 'arg2'son solo literales de cadena pasados ​​como parámetros adicionales a la tubería. Puede usar cualquier valor o referencia que esté disponible en ese ámbito (la instancia del componente actual)
Günter Zöchbauer
1
@freethebees tienes que pasar nulo
karoluS
el método de transformación no admite argumentos de matriz buen punto @Gunter
BALS
5

Utilizo Pipes en Angular 2+ para filtrar matrices de objetos. A continuación se incluyen varios argumentos de filtro, pero puede enviar solo uno si se ajusta a sus necesidades. Aquí hay un ejemplo de StackBlitz . Encontrará las claves por las que desea filtrar y luego filtrará por el valor que proporcione. En realidad es bastante simple, si suena complicado no lo es, mira el ejemplo de StackBlitz .

Aquí se llama a Pipe en una directiva * ngFor,

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

Aquí está 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;
    }
  }
}

Y aquí está el Componente que contiene el objeto a filtrar,

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

Ejemplo de StackBlitz

Ejemplo de GitHub: bifurca una copia de trabajo de este ejemplo aquí

*Tenga en cuenta que en una respuesta proporcionada por Gunter, Gunter afirma que las matrices ya no se usan como interfaces de filtro, pero busqué en el enlace que proporciona y no encontré nada que hablara de esa afirmación. Además, el ejemplo de StackBlitz proporcionado muestra que este código funciona según lo previsto en Angular 6.1.9. Funcionará en Angular 2+.

Happy Coding :-)

usuario3777549
fuente
No tiene sentido pasar una matriz única con múltiples entradas en lugar de pasar parámetros múltiples directamente a la tubería.
BrunoJCM
La matriz contiene objetos. Los objetos pueden contener múltiples pares de valores clave utilizados para crear consultas dinámicas donde puede buscar registros coincidentes utilizando nombres de columna en comparación con los valores de fila de la columna. No obtendría este nivel de consulta dinámica pasando parámetros CSV.
user3777549
-2

Extendido desde: user3777549

Filtro de valores múltiples en un conjunto de datos (solo referencia a la clave de título)

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
fuente