Как получить размер отфильтрованного (поданного) набора в 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 в качестве второго аргумента. И в строке класса передать результирующий массив.