angular - MatTable med sortering ser ikke ut til å sortere kolonnen
Jeg har et enkelt design jeg jobbet med. I modul-filen har jeg lagt til importene: MatSortModule og MatTableModule. Når jeg ser på komponenten jeg laget, var den enkel:
<table mat-table [dataSource]="dataSource"
matSort>
<ng-container matColumnDef="interface"> <!-- vvv This area may have some importance vvv -->
<th mat-header-cell *matHeaderCellDef mat-sort-header id="interface">Interface</th>
<td mat-cell *matCellDef="let element"><span>{{element.interface}}</span></td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
og deretter TS-filen:
class GridComponent {
dataSource = null
displayedColumns = ["interface"];
@ViewChild(MatSort, {static: true}) sort: MatSort;
@Input() set data(val: any[]) {
this._data = val;
getInfo();
}
get data () { return this._data; }
private _data: any[];
ngOnInit() {
this.dataSource = new MatTableDataSource([])
this.dataSource.sort = this.sort
}
getInfo() {
this._service.get(this._data).subscribe( data => {
/// For the ease of understanding. assume data is defined below.
const arr = [{"interface":"foo"},{"interface":"bar"}]
this.dataSource = new MatTableDataSource(arr)
this.dataSource.sort = this.sort
});
}
}
Rutenettet gjengir alle radene, og bryteren viser osv. Når jeg derimot trykker på den, blir ikke informasjonen omordnet.
Er det noe jeg går glipp av? Jeg så noen eksempler som sa at jeg måtte gjøre: this.dataSource.sort=this.sort, men jeg forstår egentlig ikke hensikten med det, og om det på noen måte forstyrrer sorteringsmekanismen.
Når jeg ser på kodesamplet nederst på: https://material.angular.io/components/sort/overview, ble jeg forvirret da jeg ikke så noen form for ID bli brukt, eller tilordnet mat-sort-header-egenskapen, men i noen av APIene stod det at man skulle gjøre det
Jeg skulle gjerne hatt litt avklaring.
Rediger: Jeg ser etter et dynamisk svar, et som lar meg enkelt endre dataene i datakilden. Akkurat nå, utenfor omfanget av problemet, har jeg en input som lar meg endre dataserien knyttet til datakilden, så jeg jobber mot å holde det kapslet på en slik måte at jeg kan håndtere å sette egenskaper utenfor Initializers av komponenter.
Svar #1
Det finnes en innebygd endring for matSort som du kan fange for å håndtere sortering. Dette omgår linjene: this.dataSource.sort=this.sort;. Så du kan kutte ut all den koden.
<table mat-table
[dataSource]="dataSource"
matSort
(matSortChange)="sortData($event)"></table>
og så i koden kan du skrive:
sortData(sort: Sort){
// Sort sorts the current list, but it wasnt updating it unless i reassigned.
this.dataSource.data = this.dataSource.data.sort((a, b) => {
const isAsc = sort.direction === 'asc';
return this._compare(a[sort.active], b[sort.active], isAsc);
});
}
private _compare(a: number | string, b: number | string, isAsc: boolean) {
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}
Det andre svaret fungerte ikke i det hele tatt for meg, men nå flyter alt godt.
Siden det finnes 3 tilstander for sort.direction, 'asc', 'desc', og '', så for den tomme strengen vil jeg sette datasource lik den opprinnelige listeordenen.
Her er den modifiserte komponenten, med utkommenterte områder som nå kan slettes
class GridComponent {
/// Initialize the datasource we will be augmenting its inner data.
dataSource: MatTableDataSource<any> = new MatTableDataSource();
displayedColumns = ["interface"];
//@ViewChild(MatSort, {static: true}) sort: MatSort;
@Input() set data(val: any[]) {
this._data = val;
getInfo();
}
get data () { return this._data; }
private _data: any[];
ngOnInit() {
//this.dataSource = new MatTableDataSource([])
//this.dataSource.sort = this.sort
}
getInfo() {
this._service.get(this._data).subscribe( data => {
/// For the ease of understanding. assume data is defined below.
const arr = [{"interface":"foo"},{"interface":"bar"}]
/// Updated the below line to just update data.
this.dataSource.data = arr;
//this.dataSource.sort = this.sort
});
}
sortData(sort: Sort){
// Sort sorts the current list, but it wasnt updating it unless i reassigned.
this.dataSource.data = this.dataSource.data.sort((a, b) => {
const isAsc = sort.direction === 'asc';
return this._compare(a[sort.active], b[sort.active], isAsc);
});
}
private _compare(a: number | string, b: number | string, isAsc: boolean) {
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}
}
Svar #2
Ja, for at sorteringen skal fungere for mat-datatabellen, må du bruke this.dataSource.sort=this.sort innenfor ngOnInit()
ngOnInit() {
this.dataSource = new MatTableDataSource<FooModel>(foobar);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
Legg merke til hvordan datakilden kan oppdateres fra abonnementet ditt på tjenesten:
this.fooService.getFoobar(this.isFoo).subscribe((foobar: Foo[]) => {
if (foobars != null) {
this.dataSource = new MatTableDataSource<Foo>(foobar);
this.dataSource.sort = this.sort;
