Как получить размер отфильтрованного (поданного) набора в angular2

Я написал свой собственный фильтр, когда он исчез в angular2:

import {Pipe, PipeTransform} from 'angular2/core';

@Pipe({
  name: 'myFilter'
})
export class MyFilter implements PipeTransform {
  transform(customerData: Array<Object>, args: any[]) {
    if (customerData == undefined) {
      return;
    }
    var re = new RegExp(args[0]);
    return customerData.filter((item) => re.test(item.customerId));
  }
}

И используйте его в моем шаблоне:

<tr *ngFor="#singleCustomerData of customerData | myFilter:searchTerm">
  ...
</tr>

Теперь я хотел бы посмотреть, сколько совпадений возвращает труба. Таким образом, по существу размер возвращаемого массива.

В angular 1.x мы смогли назначить возвращаемый набор переменной в шаблоне следующим образом:

<div ng-repeat="person in filtered = (data | filter: query)">
</div>

Но мы больше не можем назначать переменные в шаблонах в angular2.

Итак, как мне получить размер отфильтрованного набора без одновременного вызова фильтра?

Ответы

Ответ 1

оригинальный

AFAIK в настоящее время нет способа сделать это напрямую. Хаком было бы добавить переменную шаблона в контент и использовать запрос ViewChildren(...) для получения созданных элементов и подсчета их.

<tr *ngFor="let singleCustomerData of customerData | myFilter:searchTerm" #someVar>
  ...
</tr>
<div>count: {{filteredItems?.length}}</div>
@ViewChildren('someVar') filteredItems;

Альтернативный подход состоял бы в том, чтобы передать ссылку на переменную счетчика на трубу, как показано в https://plnkr.co/edit/Eqjyt4qdnXezyFvCcGAL?p=preview

обновление (Angular >= 4.0.0)

Поскольку Angular 4 *ngFor поддерживает as

<tr *ngFor="let singleCustomerData of customerData | myFilter:searchTerm as result">

который вы можете использовать в шаблоне (внутри элемента, к которому добавлен *ngFor), например

  <div>{{result?.length}}</div>

Ответ 2

Вы все равно должны вызывать фильтр второй раз, но вы можете использовать его прямо следующим образом:

{{ (customerData | myFilter:searchTerm)?.length }}

Ответ 3

Я не знаю, что вы точно хотите сделать с размером, и решение Günter может удовлетворить ваши потребности.

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

@Pipe({
  name: 'dump'
})
export class DumpPipe {
  constructor(@Inject(forwardRef(() => AppComponent)) app:AppComponent) {
    this.app = app;
  }

  transform(array: Array<string>, args: string): Array<string> {
    (...)
    this.app.filteredItemLength = array.length;

    return array;
  }
}

@Component({
  (...)
})
export class AppComponent {
  (...)
}

Смотрите этот ответ:

Надеюсь, это поможет вам, Thierry

Ответ 4

Вы можете просто передать объект из компонента класса в HTML-pipe в качестве второго аргумента. И в строке класса передать результирующий массив.