Angular 5 Material 数据 Table 排序无效
Angular 5 Material Data Table sorting not working
所以我的 Angular 5 应用程序中有一个可用的 Angular Material 数据 Table,但是当我尝试添加排序功能时(基于此处的官方文档:https://material.angular.io/components/table/overview#sorting and an example here: https://stackblitz.com/angular/dnbermjydavk?file=app%2Ftable-overview-example.html ) 我无法让它工作。它似乎确实添加了排序 functionality/arrow,我可以单击它,但没有任何反应。
这是我的 HTML:
<div class="container">
<mat-table #table class="dataTable" *ngIf="showDataForm;else loadingTemplate" [dataSource]="dataSource" matSort>
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header>ID</mat-header-cell>
<mat-cell *matCellDef="let item">{{item.id}}</mat-cell>
</ng-container>
<ng-container matColumnDef="titel">
<mat-header-cell *matHeaderCellDef mat-sort-header>Titel</mat-header-cell>
<mat-cell *matCellDef="let item">{{item.titel}}</mat-cell>
</ng-container>
<ng-container matColumnDef="EADDraftingStage">
<mat-header-cell *matHeaderCellDef mat-sort-header>EADDraftingStage</mat-header-cell>
<mat-cell *matCellDef="let item">{{item.EADDraftingStage}}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="columnsToDisplay"></mat-header-row>
<mat-row *matRowDef="let item; columns: columnsToDisplay"></mat-row>
</mat-table>
<mat-paginator [pageSize]="10" [pageSizeOptions]="[5, 10, 25]" showFirstLastButtons></mat-paginator>
</div>
<ng-template #loadingTemplate>
<div>
<p>Please wait, the data is loading...</p>
<img src="../../assets/giphy.gif">
</div>
</ng-template>
<button mat-raised-button class="submitButton" color="accent" (click)="logout()">Logout and remove cookie</button>
这是我的 TS:
import { Component, OnInit, ChangeDetectorRef, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { CookieService } from 'ngx-cookie-service';
import { LoginService } from '../Services/login.service';
import { TableService } from '../Services/table.service';
import { EADProcess } from '../Classes/EADProcess';
import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { map, tap, catchError } from 'rxjs/operators';
@Component({
selector: 'app-table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {
showDataForm = false;
stringArray: string[] = [];
eadItems: EADProcess[] = [];
dataSource: MatTableDataSource<EADProcess>;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
// which columns the data table needs to display
columnsToDisplay: string[] = ['id', 'titel', 'EADDraftingStage'];
constructor(private router: Router,
private cookieService: CookieService,
private loginService: LoginService,
private tableService: TableService,
private chRef: ChangeDetectorRef) {
}
ngOnInit() {
const $this = this;
this.getAllEadItems();
}
public getAllEadItems() {
const json: any = {(data omitted for this example)};
const jsonStringified = JSON.stringify(json);
this.tableService.getAllEadItems(jsonStringified).subscribe(res => {
this.convertJsonResultToArray(res);
this.dataSource = new MatTableDataSource(this.eadItems);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
this.showDataForm = true;
});
}
public convertJsonResultToArray(res: any) {
this.stringArray = JSON.parse(res);
for (const eadItem of this.stringArray) {
const ead = new EADProcess();
ead.id = eadItem['GUID'];
ead.titel = eadItem['Title'];
ead.EADDraftingStage = eadItem['EADDraftingStage'];
this.eadItems.push(ead);
}
}
public logout() {
this.cookieService.delete('logindata');
this.loginService.setLoggedIn(false);
this.router.navigateByUrl('/login');
}
}
所以对于 re-iterate,我的数据表可以很好地显示数据,但现在我想添加排序功能,当我按下 header 单元格(s)时,它似乎并没有真正排序) 我要排序。有人看到问题了吗?
这可能是因为您的排序器没有正确绑定到您的数组。
尝试使用超时来延迟绑定:
this.convertJsonResultToArray(res);
this.dataSource = new MatTableDataSource(this.eadItems);
setTimeout(() => {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
});
this.showDataForm = true;
您遇到的问题是 mat-table 选择器中的 *ngIf。如果你检查 this.sort 你会看到它是未定义的。这有效:
export class TableComponent implements OnInit {
sort;
@ViewChild(MatSort) set content(content: ElementRef) {
this.sort = content;
if (this.sort){
this.dataSource.sort = this.sort;
}
}
我不记得我在 SO 中用作解决方案指南的答案。
如果有人仍然有问题并且需要更简洁的方法,他们可以实现 ngAfterViewInit 接口并实现它。它是在 Angular 完全初始化组件视图后调用的生命周期挂钩。
参考提问者的代码,TS可以通过以下代码更新。
import { Component, OnInit, ChangeDetectorRef, ViewChild, AfterViewInit } from '@angular/core';
...
...
export class TableComponent implements OnInit, AfterViewInit {
...
...
ngAfterViewInit() {
this.dataSource.sort = this.sort; // apply sort after view has been initialized.
}
}
export class SomeComponent implements OnInit, AfterViewInit {
public rows = [];
public dataSource = new MatTableDataSource<SomeElement>([]);
constructor(public dialogRef: MatDialogRef<SomeComponent>, @Inject(MAT_DIALOG_DATA) public data: ReportData) {}
@ViewChild(MatSort) sort;
ngOnInit(): void {
this.rows.push({...});
this.rows.push({...});
this.rows.push({...});
this.dataSource = new MatTableDataSource(this.rows);
}
ngAfterViewInit(): void {
this.dataSource.sort = this.sort;
}
所以我的 Angular 5 应用程序中有一个可用的 Angular Material 数据 Table,但是当我尝试添加排序功能时(基于此处的官方文档:https://material.angular.io/components/table/overview#sorting and an example here: https://stackblitz.com/angular/dnbermjydavk?file=app%2Ftable-overview-example.html ) 我无法让它工作。它似乎确实添加了排序 functionality/arrow,我可以单击它,但没有任何反应。
这是我的 HTML:
<div class="container">
<mat-table #table class="dataTable" *ngIf="showDataForm;else loadingTemplate" [dataSource]="dataSource" matSort>
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header>ID</mat-header-cell>
<mat-cell *matCellDef="let item">{{item.id}}</mat-cell>
</ng-container>
<ng-container matColumnDef="titel">
<mat-header-cell *matHeaderCellDef mat-sort-header>Titel</mat-header-cell>
<mat-cell *matCellDef="let item">{{item.titel}}</mat-cell>
</ng-container>
<ng-container matColumnDef="EADDraftingStage">
<mat-header-cell *matHeaderCellDef mat-sort-header>EADDraftingStage</mat-header-cell>
<mat-cell *matCellDef="let item">{{item.EADDraftingStage}}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="columnsToDisplay"></mat-header-row>
<mat-row *matRowDef="let item; columns: columnsToDisplay"></mat-row>
</mat-table>
<mat-paginator [pageSize]="10" [pageSizeOptions]="[5, 10, 25]" showFirstLastButtons></mat-paginator>
</div>
<ng-template #loadingTemplate>
<div>
<p>Please wait, the data is loading...</p>
<img src="../../assets/giphy.gif">
</div>
</ng-template>
<button mat-raised-button class="submitButton" color="accent" (click)="logout()">Logout and remove cookie</button>
这是我的 TS:
import { Component, OnInit, ChangeDetectorRef, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { CookieService } from 'ngx-cookie-service';
import { LoginService } from '../Services/login.service';
import { TableService } from '../Services/table.service';
import { EADProcess } from '../Classes/EADProcess';
import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { map, tap, catchError } from 'rxjs/operators';
@Component({
selector: 'app-table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {
showDataForm = false;
stringArray: string[] = [];
eadItems: EADProcess[] = [];
dataSource: MatTableDataSource<EADProcess>;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
// which columns the data table needs to display
columnsToDisplay: string[] = ['id', 'titel', 'EADDraftingStage'];
constructor(private router: Router,
private cookieService: CookieService,
private loginService: LoginService,
private tableService: TableService,
private chRef: ChangeDetectorRef) {
}
ngOnInit() {
const $this = this;
this.getAllEadItems();
}
public getAllEadItems() {
const json: any = {(data omitted for this example)};
const jsonStringified = JSON.stringify(json);
this.tableService.getAllEadItems(jsonStringified).subscribe(res => {
this.convertJsonResultToArray(res);
this.dataSource = new MatTableDataSource(this.eadItems);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
this.showDataForm = true;
});
}
public convertJsonResultToArray(res: any) {
this.stringArray = JSON.parse(res);
for (const eadItem of this.stringArray) {
const ead = new EADProcess();
ead.id = eadItem['GUID'];
ead.titel = eadItem['Title'];
ead.EADDraftingStage = eadItem['EADDraftingStage'];
this.eadItems.push(ead);
}
}
public logout() {
this.cookieService.delete('logindata');
this.loginService.setLoggedIn(false);
this.router.navigateByUrl('/login');
}
}
所以对于 re-iterate,我的数据表可以很好地显示数据,但现在我想添加排序功能,当我按下 header 单元格(s)时,它似乎并没有真正排序) 我要排序。有人看到问题了吗?
这可能是因为您的排序器没有正确绑定到您的数组。
尝试使用超时来延迟绑定:
this.convertJsonResultToArray(res);
this.dataSource = new MatTableDataSource(this.eadItems);
setTimeout(() => {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
});
this.showDataForm = true;
您遇到的问题是 mat-table 选择器中的 *ngIf。如果你检查 this.sort 你会看到它是未定义的。这有效:
export class TableComponent implements OnInit {
sort;
@ViewChild(MatSort) set content(content: ElementRef) {
this.sort = content;
if (this.sort){
this.dataSource.sort = this.sort;
}
}
我不记得我在 SO 中用作解决方案指南的答案。
如果有人仍然有问题并且需要更简洁的方法,他们可以实现 ngAfterViewInit 接口并实现它。它是在 Angular 完全初始化组件视图后调用的生命周期挂钩。 参考提问者的代码,TS可以通过以下代码更新。
import { Component, OnInit, ChangeDetectorRef, ViewChild, AfterViewInit } from '@angular/core';
...
...
export class TableComponent implements OnInit, AfterViewInit {
...
...
ngAfterViewInit() {
this.dataSource.sort = this.sort; // apply sort after view has been initialized.
}
}
export class SomeComponent implements OnInit, AfterViewInit {
public rows = [];
public dataSource = new MatTableDataSource<SomeElement>([]);
constructor(public dialogRef: MatDialogRef<SomeComponent>, @Inject(MAT_DIALOG_DATA) public data: ReportData) {}
@ViewChild(MatSort) sort;
ngOnInit(): void {
this.rows.push({...});
this.rows.push({...});
this.rows.push({...});
this.dataSource = new MatTableDataSource(this.rows);
}
ngAfterViewInit(): void {
this.dataSource.sort = this.sort;
}