recorrer example array angular angular2-directives

angular - example - Cómo encontrar el recuento de elementos en un ngFor después de haber aplicado los conductos



ngfor order by angular 4 (7)

Así que encontré una solución para esto.

Creé una tubería que toma una referencia de objeto y actualiza una propiedad con el recuento que actualmente pasa a través de la tubería.

@Pipe({ name: ''count'' }) export class CountPipe implements PipeTransform { transform(value, args) { if (!args) { return value; }else if (typeof args === "object"){ //Update specified object key with count being passed through args.object[args.key] = value.length; return value; }else{ return value; } } }

Luego, en su vista, vincule un componente de paginación como tal.

pagination-controls(#controls="", [items]="items.length", (onChange)="o") tbody tr(*ngFor=`let item of items | filter_pipe: { .... } | count: { object: controls , key: ''items'' } | pagination_pipe: { ... } `)

Una vez que la propiedad de recuento se extrae de la tubería al componente actual o al componente secundario, puede hacer cualquier cosa con él.

Tengo un ngPara crear filas en una tabla que está filtrada y paginada.

<tr *ngFor="#d of data.results | filter:filterText | pagination:resultsPerPage:currentPage">

Hay otro elemento en la página que muestra el número de registros mostrados. Estos elementos están inicialmente ligados a los datos. Longitud de los resultados.

¿Cómo obtengo la longitud de los datos que se muestran después de que se haya aplicado la tubería de filtro para poder mostrarlos correctamente? Ninguna de las variables locales proporcionadas en ngFor parece dar cuenta de esto.


En mi caso, necesitaba ejecutar los elementos filtrados y realizar algunos análisis.

Mis soluciones es simplemente pasar una función y devolver la matriz en el último canal. También puedes crear un conducto especialmente para esto, pero lo he agregado a mi último conducto en los filtros:

HTML

<divclass="card" *ngFor="let job of jobs | employee:jobFilter.selectedEmployee | managerStatus:jobFilter.selectedStatus | dateOrder:jobFilter">

Componente

this.jobFilter = { jobStatuses: {}, // status labels ordering: ''asc'', selectedEmployee: {}, selectedStatus: {}, // results status fn: this.parseFilteredArr }; parseFilteredArr(arr) { console.log(arr); }

Tubo

import { Pipe, PipeTransform } from ''@angular/core''; @Pipe({ name: ''dateOrder'' }) export class DateOrderPipe implements PipeTransform { transform(value: any, args?: any): any { const arr = Array.isArray(value) ? value.reverse() : value; args.fn(arr); return arr; } }

Como pueden ver, he llamado a la función en la tubería.

args.fn (arr);

Y ahora puede procesarlo en el controlador.


Encontré el mismo problema, aunque la respuesta de @bixelbits fue aprobada, pero no la encontré ideal, especialmente para datos grandes.

En lugar de devolver la matriz original en cada elemento, creo que es mejor evitar Pipes para este problema, al menos con la implementación actual de Angular 2 (rc4).

Una mejor solución sería utilizar la función del componente normal para filtrar los datos, algo como a continuación:

// mycomponent.component.ts filter() { let arr = this.data.filter( // just an example item => item.toLowerCase().includes( // term is a local variable I get it''s from <input> this.term.toLowerCase() ) ); this.filteredLength = arr.length; return arr; }

Luego, en la plantilla:

<ul> <li *ngFor="let el of filter()"> {{ el | json }} </li> </ul> // mycomponent.component.html <p > There are {{ filteredLength }} element(s) in this page</p>

A menos que realmente desee utilizar Pipes , le recomendaría que los evite en situaciones como el ejemplo anterior.


Encontré que la solución más simple es la siguiente:

  1. En su componente: agregue un campo que contendrá el conteo actual

filterMetadata = { count: 0 };

  1. En su plantilla: agregue filterMetadata como un parámetro a la tubería de filtro

<tr *ngFor="#d of data.results | filter:filterText:filterMetadata | pagination:resultsPerPage:currentPage">

  1. interpolar filterMetadata.count en el elemento que muestra el número de registros mostrados.

<span> {{filterMetadata.count}} records displayed</span>

  1. En la tubería de filtro, actualice el campo filterMetadata.count cuando haya terminado con el filtrado

transform(items, ..., filterMetadata) { // filtering let filteredItems = filter(items); filterMetadata.count = filteredItems.length; return filteredItems; }

Esta solución todavía utiliza tuberías puras, por lo que no hay degradaciones de rendimiento. Si tiene varias tuberías que filtran, se debe agregar filterMetadata como un parámetro para todas ellas, ya que angular detiene la secuencia de la tubería en cuanto la tubería devuelve una matriz vacía, por lo que no puede simplemente agregarla a la primera o último tubo de filtración.


Ese no es exactamente el propósito de la pregunta original, pero también estaba buscando una manera de mostrar el recuento de elementos una vez que se han aplicado todas las canalizaciones. Al combinar el índice y los últimos valores proporcionados por ngFor, encontré esta otra solución:

<div *ngFor="#item of (items | filter); #i = index; #last = last"> ... <div id="counter_id" *ngIf="last">{{index + 1}} results</div> </div>


Puede obtener el recuento de los elementos transformando la matriz dentro de una canalización.

La idea es que la tubería transformaría la matriz en otra matriz donde cada elemento tiene una propiedad de elemento y una propiedad principal que representa la matriz filtrada (u original):

@Pipe({ name: ''withParent'', pure: false }) export class WithParentPipe implements PipeTransform { transform(value: Array<any>, args: any[] = null): any { return value.map(t=> { return { item: t, parent: value } }); } }

Así es como se usaría:

<tr *ngFor="#d of data.results | filter:filterText | pagination:resultsPerPage:currentPage | withParent"> Count: {{d.parent.length }} Item: {{ d.item.name}} </tr>


Una forma es usar variables de plantilla con @ViewChildren()

<tr #myVar *ngFor="let d of data.results | filter:filterText | pagination:resultsPerPage:currentPage">

@ViewChildren(''myVar'') createdItems; ngAfterViewInit() { console.log(this.createdItems.toArray().length); }