Я оказался в такой ситуации, я уже использовал угловой материал, поэтому решил продолжить.
Вот так я обработал поиск и сортировку таблицы
Я создал класс класса источника данных для обработки данных http, внутри него я вызываю службу, которая делает запрос данных http
import {Domanda} from '../models';
import {DataSource} from '@angular/cdk/table';
import {BehaviorSubject, Observable, of} from 'rxjs';
import {catchError, finalize} from 'rxjs/operators';
import {CollectionViewer} from '@angular/cdk/collections';
import {ApiService} from './api.service';
export class ListaDomandeDatasource implements DataSource<Domanda> {
private domandeSubject = new BehaviorSubject<Domanda[]>([]);
// Gestisce il caricamento della tabella
private loadingSubject = new BehaviorSubject<boolean>(false);
public loading$ = this.loadingSubject.asObservable();
constructor(private apiService: ApiService) {
}
cercaDomande(idConcorso: number,
keywords: string,
sortOrder: string,
pageIndex: number,
pageSize: number) {
this.loadingSubject.next(true);
this.apiService.cercaDomande(idConcorso, keywords, sortOrder,
pageIndex, pageSize).pipe(
catchError(() => of([])),
finalize(() => this.loadingSubject.next(false))
)
.subscribe(lessons => this.domandeSubject.next(lessons));
}
connect(collectionViewer: CollectionViewer): Observable<Domanda[]> {
console.log('Connecting data source');
return this.domandeSubject.asObservable();
}
disconnect(collectionViewer: CollectionViewer): void {
this.domandeSubject.complete();
this.loadingSubject.complete();
}
}
В компоненте, где определена таблица, я просто играю с rxjs, чтобы прослушивать ввод, но на самом деле логическая часть - все это делает бэкэнд.
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {Concorso} from '../../../../core/models';
import {MatPaginator, MatSort} from '@angular/material';
import {ActivatedRoute, Router} from '@angular/router';
import {ApiService} from '../../../../core/services';
import {ListaDomandeDatasource} from '../../../../core/services/lista-domande.datasource';
import {fromEvent, merge} from 'rxjs';
import {debounceTime, distinctUntilChanged, tap} from 'rxjs/operators';
@Component({
selector: 'app-lista-domande',
templateUrl: './concorso.component.html',
styleUrls: ['./concorso.component.scss']
})
export class ConcorsoComponent implements OnInit, AfterViewInit {
nomeColonne: string[] = ['id', 'nominativo', 'dataNascita', 'dataProva', 'nomeProva', 'open'];
dataSource: ListaDomandeDatasource;
concorso: Concorso; // Risultato del resolver esistenza concorso
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
@ViewChild(MatSort, { static: true }) sort: MatSort;
@ViewChild('input', { static: true }) input: ElementRef;
constructor(private api: ApiService,
private router: Router,
private route: ActivatedRoute) {
}
ngOnInit() {
/* Se si resta sulla stessa pagina e si cambiano solo i parametri la pagina non viene ricaricata, dunque ngOnInit non viene triggerato,
* per ovviare a ciò resto in ascolto dei parametri che cambiano e chiamo la lista delle domande */
this.route.params.subscribe(
() => {
this.concorso = this.route.snapshot.data.concorso;
}
);
// Istanzio il datasource passandogli il service
this.dataSource = new ListaDomandeDatasource(this.api);
this.dataSource.cercaDomande(this.concorso.id, '', 'asc', 0, 3);
}
ngAfterViewInit() {
this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);
// Triggero evento input nella searchbar
fromEvent(this.input.nativeElement, 'keyup')
.pipe(
debounceTime(150),
distinctUntilChanged(),
tap(() => {
this.paginator.pageIndex = 0;
this.CaricaPaginaDomande();
})
)
.subscribe();
merge(this.sort.sortChange, this.paginator.page)
.pipe(
tap(() => this.CaricaPaginaDomande())
)
.subscribe();
}
CaricaPaginaDomande() {
this.dataSource.cercaDomande(
this.concorso.id,
this.input.nativeElement.value,
this.sort.direction,
this.paginator.pageIndex,
this.paginator.pageSize);
}
GotoDomanda(id) {
return 'domanda/' + id;
}
}
И это HTML-часть:
<h2>CONCORSO: {{concorso.id}}</h2>
<div fxLayout="column">
<mat-form-field>
<label for="searchbar"></label>
<input matInput id="searchbar" placeholder="Cerca candidato per il suo identificativo" #input>
<mat-icon matPrefix>search</mat-icon>
</mat-form-field>
<div class="spinner-container" *ngIf="dataSource.loading$ | async">
<mat-spinner></mat-spinner>
</div>
<table fxFill
mat-table [dataSource]="dataSource"
matSort matSortActive="created" matSortDisableClear matSortDirection="asc">
<!-- Colonna id domande-->
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef>#</th>
<td mat-cell *matCellDef="let row">{{row.DomandaConcorso.IdDomanda}}</td>
</ng-container>
<!-- Colonna cognome nome canditato -->
<ng-container matColumnDef="nominativo">
<th mat-header-cell *matHeaderCellDef>Nominativo</th>
<td mat-cell *matCellDef="let row">{{row.Anagrafica.Cognome}} {{row.Anagrafica.Nome}}</td>
</ng-container>
<!-- Colonna data di nascita candidato -->
<ng-container matColumnDef="dataNascita">
<th mat-header-cell *matHeaderCellDef>Data di nascita</th>
<td mat-cell *matCellDef="let row">{{row.Anagrafica.DataNascita}}</td>
</ng-container>
<!-- Colonna data prova candidato -->
<ng-container matColumnDef="dataProva">
<th mat-header-cell *matHeaderCellDef>Data prova</th>
<td mat-cell *matCellDef="let row">{{row.prove[2].dataProva}}</td>
</ng-container>
<!-- Colonna nome ultima prova -->
<ng-container matColumnDef="nomeProva">
<th mat-header-cell *matHeaderCellDef>Data prova</th>
<td mat-cell *matCellDef="let row">{{row.prove[2].nomeProva}}</td>
</ng-container>
<!-- Colonna bottone apri singola domande -->
<ng-container matColumnDef="open">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let row" >
<button [routerLink]="GotoDomanda(row.DomandaConcorso.IdDomanda)" mat-flat-button>VISUALIZZA</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="nomeColonne"></tr>
<tr mat-row *matRowDef="let row; columns: nomeColonne;"></tr>
</table>
<mat-paginator [length]="20" [pageSize]="3"
[pageSizeOptions]="[3, 5, 10]"></mat-paginator>
</div>
Все это невозможно сделать, не прочитав документы с данными: https://material.angular.io/components/categories/tables
Если у вас есть еще вопросы, скажите мне.