Как мне вызвать канал Angular 2 с несколькими аргументами?

205

Я знаю, что могу назвать трубу вот так:

{{ myData | date:'fullDate' }}

Здесь труба даты принимает только один аргумент. Каков синтаксис для вызова канала с большим количеством параметров, из шаблона HTML компонента и непосредственно в коде?

Эран Шаби
источник

Ответы:

406

В шаблоне вашего компонента вы можете использовать несколько аргументов, разделяя их двоеточиями:

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

Из вашего кода это будет выглядеть так:

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

И в вашей функции преобразования внутри вашего канала вы можете использовать такие аргументы:

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

Бета 16 и ранее (2016-04-26)

Каналы принимают массив, содержащий все аргументы, поэтому их нужно вызывать так:

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

И ваша функция преобразования будет выглядеть так:

export class MyPipe implements PipeTransform {    
    transform(value:any, args:any[]):any {
        var arg1 = args[0];
        var arg2 = args[1];
        ...
    }
}
Эран Шаби
источник
8
Этот дизайн глупый. Мне нужно проверять документ каждый раз, когда я сталкиваюсь с этой проблемой
tom10271
Как бы выглядел бит шаблона, если arg1и arg2где оба необязательны, и вы только хотели передать arg2?
freethebees
если вы передадите undefinedв качестве первого аргумента, он получит значение по умолчанию.
Эран Шаби
3
в настоящее время вместо transform(value:any, arg1:any, arg2:any, arg3:any)использования отдыха оператор чувствует себя лучше, я думаю:transform(value:any, ...args:any[])
MKB
почему transform (... args) вызывает ошибку, а transform (value, ... args) нет?
Шелдиб
45

Вы пропускаете реальную трубу.

{{ myData | date:'fullDate' }}

Несколько параметров могут быть разделены двоеточием (:).

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

Также вы можете цепные трубы, вот так:

{{ myData | date:'fullDate' | myPipe:'arg1':'arg2':'arg3' }}
Евгений
источник
25

Начиная с beta.16, параметры больше не передаются transform()методу в виде массива , а в виде отдельных параметров:

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

Теперь каналы принимают переменное число аргументов, а не массив, содержащий все аргументы.

Гюнтер Цохбауэр
источник
Как бы выглядел бит шаблона, если arg1и arg2где оба необязательны, и вы только хотели передать arg2?
freethebees
Можем ли мы использовать другие имена переменных, кроме arg1? Как isFullDate. Я просто спрашиваю, потому что каждый пример использует это.
Сабитпокер
'arg1'и 'arg2'являются просто строковыми литералами, передаваемыми в качестве дополнительных параметров в канал. Вы можете использовать любое значение или ссылку, которые доступны в этой области (текущий экземпляр компонента)
Günter Zöchbauer
1
@freethebees, ты должен пройти null
karoluS
метод преобразования не поддерживает массив ARGS хорошую точку @Gunter
BALS
5

Я использую Pipes в Angular 2+ для фильтрации массивов объектов. Следующее принимает несколько аргументов фильтра, но вы можете отправить только один, если это соответствует вашим потребностям. Вот пример StackBlitz . Он найдет ключи, по которым вы хотите отфильтровать, а затем отфильтрует по заданному вами значению. Это на самом деле довольно просто, если это звучит сложно, не так, посмотрите пример StackBlitz .

Здесь труба вызывается в директиве * ngFor,

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

Вот Труба,

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

А вот компонент, содержащий объект для фильтрации,

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

Пример GitHub: разместите рабочую копию этого примера здесь

*Пожалуйста, обратите внимание что в ответе Гантера Гунтер утверждает, что массивы больше не используются в качестве интерфейсов фильтров, но я искал ссылку, которую он предоставляет, и не нашел ничего, касающегося этого утверждения. Кроме того, в приведенном примере StackBlitz этот код работает так, как задумано в Angular 6.1.9. Это будет работать в Angular 2+.

Удачного кодирования :-)

user3777549
источник
Нет смысла передавать один массив с несколькими записями вместо передачи нескольких параметров непосредственно в канал.
BrunoJCM
Массив содержит объекты. Объекты могут содержать несколько пар ключ-значение, используемых для создания динамических запросов, в которых вы можете искать совпадающие записи, используя имена столбцов по сравнению со значениями строк столбцов. Вы не получите такой уровень динамических запросов, передавая параметры CSV.
user3777549
-2

Расширен от: user3777549

Многозначный фильтр для одного набора данных (только ссылка на ключ заголовка)

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
источник