【发布时间】:2018-08-10 12:52:20
【问题描述】:
我有分页的数据列表,它支持自定义每页的数量项目。首先,我使用来自material.angular.io 的official example。
但在我的代码分页不起作用。角度丢失分页对象。当我从 IU 更改 Items per page 值时,注意到 todo。分页设置不起作用,我的页面上有 2000 个元素。来自服务器的所有数据都呈现在一个表格页面上。
<div *ngIf="dataIsLoaded">
<div class="example-container mat-elevation-z8">
<mat-table [dataSource]="dataSource" matSort>
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header> ID</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.id}}</mat-cell>
</ng-container>
<ng-container matColumnDef="ip">
<mat-header-cell *matHeaderCellDef mat-sort-header> IP</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.ip}}</mat-cell>
</ng-container>
<ng-container matColumnDef="password">
<mat-header-cell *matHeaderCellDef mat-sort-header> Password</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.password}}</mat-cell>
</ng-container>
<ng-container matColumnDef="startDate">
<mat-header-cell *matHeaderCellDef mat-sort-header> Start Date</mat-header-cell>
<mat-cell *matCellDef="let row" [style.color]="row.color"> {{row.activatedDate}}</mat-cell>
</ng-container>
<ng-container matColumnDef="endDate">
<mat-header-cell *matHeaderCellDef mat-sort-header> End Date</mat-header-cell>
<mat-cell *matCellDef="let row" [style.color]="row.color"> {{row.deactivatedDate}}</mat-cell>
</ng-container>
<!-- Detail button -->
<ng-container matColumnDef="detail">
<mat-header-cell *matHeaderCellDef mat-sort-header> Detail</mat-header-cell>
<mat-cell *matCellDef="let row" [style.color]="row.color">
<button mat-raised-button color="primary" (click)="getDetail(row.id)">Detail</button>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;">
</mat-row>
</mat-table>
<mat-paginator #paginator
[pageSize]="10"
[pageSizeOptions]="[5, 10, 25]"
[showFirstLastButtons]="true">
</mat-paginator>
</div>
</div>
还有TS端:
export class VdsListComponent implements OnInit, AfterViewInit {
displayedColumns = [
'id',
'ip',
'password',
'startDate',
'endDate',
'detail'
];
dataSource: MatTableDataSource<Vds>;
filterForm: FormGroup;
dataIsLoaded = false;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
constructor(private vdsService: VdsService) {
}
ngOnInit() {
this.filterForm = new FormGroup({
'ip': new FormControl(null, []),
'id': new FormControl(null, []),
'dateFrom': new FormControl(null, []),
'dateTo': new FormControl(null, [])
});
this.vdsService.getVds().subscribe((vds: Vds[]) => {
this.dataSource = new MatTableDataSource(vds);
this.dataSource.paginator = this.paginator;
this.dataIsLoaded = true;
});
}
}
现在不会出现控制台错误。
帮助我了解为什么我的代码不起作用并修复它。
【问题讨论】:
-
错误信息说明了一切:您正在尝试在 this.dataSource 上设置分页器,但此时 this.dataSource 未定义,因为它只是稍后在回调异步 observable 时初始化由 this.vdsService.getVds() 返回。
-
@JB Nizet 我更新了问题。一开始,我将分页器设置为 ngOnInit() 并且没有收到错误,但是分页不起作用,我在官方示例中执行了操作 - 将设置分页器移动到 ngAfterViewInit() 并收到此错误。我在 ngOnInit() 中返回了 set paginator。现在控制台很清楚,但分页不起作用。一页上的所有数据。
-
分页器需要定义视图,因为它是一个 ViewChild。 ngOnInit 中还没有该视图。您的初始代码比新代码少错误。阅读我在评论中所说的内容,而不是随意尝试。
-
@JB Nizet 我明白了! ngOnInit() 中不存在分页器。我需要在构建视图后设置分页器。但是哪里?我认为 ngAfterViewInit() 在视图初始化后调用。如何知道 ViewChild 会被初始化?
-
是的。但请阅读错误消息,并阅读我的评论。问题不在于分页器未定义。它是在 ngAfterViewInit 内部使用时。未定义的是
this.dataSource。因此出现错误:Cannot set property 'paginator' of undefined,在尝试执行this.dataSource.paginator = ...时。