Мне нужно было решить очень похожую проблему, которая заключалась в локальной сортировке данных для таблицы mat с сервера с помощью запроса http.post (или http.get), выполняемого из автономной службы.Я использовал MatTableDataSource, чтобы сделать это вопреки советам Андреаса (см. Выше).
Убедитесь, что вы импортировали их в app.module.ts:
import { HttpClientModule } from '@angular/common/http';
import { MatTableModule } from '@angular/material/table';
import { MatSortModule } from '@angular/material';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
@NgModule({
....,
imports: [
....,
HttpClientModule,
MatTableModule,
MatSortModule,
MatProgressSpinnerModule,
],
....,
})
Мой HTML (app.component.html):
<div class="example-container mat-elevation-z8">
<div class="example-loading-shade"
*ngIf="isLoadingResults">
<mat-spinner *ngIf="isLoadingResults" color="accent"></mat-spinner>
</div>
<div class="example-table-container">
<table mat-table matSort [dataSource]="datasrc" hover="true" class="example-table">
<ng-container matColumnDef="name" sticky>
<th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<ng-container matColumnDef="age">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Age </th>
<td mat-cell *matCellDef="let element"> {{element.age}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
<tr mat-row
*matRowDef="let row; let i = index; columns: displayedColumns;"
(click)="onSelectRow(i)"
class="example-element-row"></tr>
</table>
</div>
</div>
Компонент приложения (app.component.ts):
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { merge, Observable, of as observableOf } from 'rxjs';
import { catchError, map, startWith, switchMap } from 'rxjs/operators';
import { MatSort, MatTableDataSource, MatTable } from '@angular/material';
import { MatTableModule } from '@angular/material/table';
import { MyDataService } from './mydata.service';
import { Person, RootObject } from './mydata.interface';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
displayedColumns: string [] = [
'name',
'age',
];
mydataDB: MyDataService | null;
dataSource: Person[] = [];
datasrc = new MatTableDataSource<object>(this.dataSource);
isLoadingResults = true;
@ViewChild(MatSort) sort: MatSort;
@ViewChild(MatTable) table: MatTable<any>;
constructor(
private myDataService: MyDataService,
private http: HttpClient
) { }
ngAfterViewInit() {
this.updateTable();
}
updateTable() {
this.mydataDB = new MyDataService(this.http);
merge(this.sort.sortChange)
.pipe(
startWith({}),
switchMap(() => {
this.isLoadingResults = true;
return this.mydataDB!.getData();
}),
map(data => {
this.isLoadingResults = false;
return data;
}),
catchError(() => {
this.isLoadingResults = false;
return observableOf([]);
})
).subscribe(data => {
this.dataSource = data['response'];
this.datasrc = new MatTableDataSource(this.dataSource);
this.datasrc.sort = this.sort;
this.table.renderRows();
});
}
}
Интерфейс (mydata.interface.ts):
export interface RootObject {
response: Person
}
export interface Person {
name: string;
age: number;
}
Моя служба данных (mydata.service.ts):
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, Subscriber } from 'rxjs';
import { tap, map, filter } from 'rxjs/operators';
import { RootObject } from './remittances.interface';
@Injectable()
export class MyDataService{
//Change this to the url you need
public httpRoot = 'http://www.myapi.com/api/';
private postBody: {};
constructor(
private http: HttpClient,
) {}
getData(): Observable<RootObject[]> {
//Add any APi parameters here if needed
this.postBody = {
"name":"getPeopleAPI",
"params":{
"filter":"country"
}
};
return this.http.post<RootObject[]>(
this.httpRoot,
this.postBody,
{
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
}
);
}
}
И, наконец, CSS (app.component.css):
.example-container {
position: relative;
min-height: 400px;
}
.example-table-container {
position: relative;
max-height: 400px;
overflow: auto;
}
.example-loading-shade {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, 0.15);
z-index: 2;
display: flex;
align-items: center;
justify-content: center;
}
/* Column Widths */
.mat-column-number,
.mat-column-state {
max-width: 64px;
}
.mat-column-created {
max-width: 124px;
}
Вам необходимо изменить интерфейсы длясопоставьте данные, которые вам нужны от API, и поместите их соответствующим образом в таблицу.Отличным инструментом для этого является http://www.jsontots.com/.
Всякий раз, когда вам нужно изменить данные в таблице, вы можете просто вызвать функцию this.updateTable () в app.component.ts и передать переменные черезgetData () в mydata.service.ts для отправки их в качестве параметров в API.Это заняло у меня много времени, чтобы хорошо работать, поэтому надеюсь, что это кому-нибудь поможет.