En mi código, tengo una lista JSON que obtengo datos usando fromFetch(). Puedo obtener los datos y agruparlos en la consola por ID de categoría. Quiero mostrar una tabla de productos solo con la categoría Id de 2. En este momento, solo puedo mostrar una tabla uniforme sin la condición que quiero. ¿Qué debo hacer para lograr lo que quiero?
HTML:
<div> <table mat-table [dataSource]="items$ | async" class="mat-elevation-z8" matSort > <ng-container matColumnDef="categoryId"> <th mat-header-cell *matHeaderCellDef mat-sort-header>Category Id</th> <td mat-cell *matCellDef="let item">{{ item.categoryId }}</td> </ng-container> <ng-container matColumnDef="name"> <th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th> <td mat-cell *matCellDef="let item">{{ item.name }}</td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr> </table> </div>
TS:
items$: Observable<Item[]>; dataSource: MatTableDataSource<Item>; @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; @ViewChild(MatSort, { static: true }) sort: MatSort; displayedColumns: string[] = ['categoryId', 'name']; ngAfterViewInit(): void { this.items$ = fromFetch( 'someitems/data/items.json' ).pipe( switchMap((response) => { return response.json(); }) ); this.items$.subscribe(function (result) { const grouped = _.groupBy(result, (res) => res.categoryId); this.dataSource = result; this.dataSource.paginator = this.paginator; this.dataSource.sort = this.sort; console.log(grouped); }); }
Puede extender los items$
observables, para realizar más operaciones utilizando otro operador de map
. Aplique su lógica de transformación de objetos en la función de map
.
Actualizar
En el lado de la plantilla, tuvo que agregar una fila separada para la fila groupBy, ¿verdad? Puede usar la cláusula when
en otro mat-row
. Dentro de la cláusula when puede agregar la función isGroup
, que ayuda a verificar si mostrar la fila groupBy
o no.
Modelo
<tr mat-row *matRowDef="let row; columns: ['initial']; when: isGroup" ></tr>
TS
isGroup(index, item): boolean { return item.isGroupBy; } this.items$ = fromFetch( 'someitems/data/items.json' ).pipe( switchMap((response) => { return response.json(); }), map((data) => { const grouped = groupBy(data, (res) => res.categoryId); let output = []; for (let group in grouped) { output.push({ initial: group, isGroupBy: true }); output = output.concat(grouped[group]); } return output; }) );
Puede usar la función como argumento de fuente de datos
<table mat-table [dataSource]="fetch(2) | async" class="mat-elevation-z8" matSort>
y la función se verá algo como:
fetch(catId): MatTableDataSource<Item>{ const data = this.items$.filter(row => row.categoryId === catId); const ds = new MatTableDataSource<Item>(data); ds.paginator = this.paginator; ds.sort = this.sort; return ds; }