使用我设法从 API 中找到的任何类型的事件进行选择和自动完成,最终都会导致 MatPaginator“落后一步”,例如虽然过滤后的数据长度应该只有 200,但 paginator.length 仍然停留在 800,只有在下一次选择后才变成 200。
.html
<mat-form-field class="filterField">
<input matInput
(keyup)="updateManualPage(1)"
placeholder="Filter"
formControlName="filterParam2"
[matAutocomplete]="autoSingleSelect">
<mat-autocomplete #autoSingleSelect="matAutocomplete"
class="filterSelect"
panelClass="filterSelect">
<mat-option *ngFor="let option of dropdownSingleFilteredOptions | async"
[value]="option.param2">
{{option.param2}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<div id="paginationContainer">
<div id="pageNumberButtons">
<button mat-button
[class.hiddenPage]="!(manualPage > 3)"
(click)="updateManualPage(1)">
1
</button>
...etc
</div>
<mat-paginator [length]="tableDataSource.data.length"
[pageSize]="10"
[pageSizeOptions]="[5, 10, 25]"
showFirstLastButtons
aria-label="Select page"
[selectConfig]="{ panelClass: 'paginatorDropdown' }"
(page)="onPaginateChange($event)">
</mat-paginator>
</div>
.ts
tableDataSource = new MatTableDataSource<randomInterface>(testArray);
maxPages: number = 0;
manualPages: number = 1;
ngOnInit() {
this.tableDataSource.filterPredicate = this.customFilter;
}
ngAfterViewInit() {
this.updatePaginator();
this.updateMaxPages();
}
onPaginateChange(event: PageEvent) {
this.manualPage = event.pageIndex + 1;
this.updatePaginator();
this.updateMaxPages();
}
updateManualPage(page: number) {
this.manualPage = page;
this.tableDataSource.paginator!.pageIndex = page - 1;
this.updatePaginator();
this.updateMaxPages();
}
updatePaginator() {
this.tableDataSource.paginator = this.paginator;
}
updateMaxPages() {
this.maxPages = Math.ceil((this.tableDataSource.paginator?.length ?? 0) / (this.tableDataSource.paginator?.pageSize ?? 1));
}
customFilter = (data: randomInterface, filter: string) => {
const filterData = JSON.parse(filter);
let find: boolean = !filterData.filterParam1 || data.param1.toString().includes(filterData.filterParam1.toString());
find = find && (!filterData.filterParam2 || data.param2.toLowerCase().includes(filterData.filterParam2.toLowerCase()));
find = find && (!filterData.filterParam3 || filterData.filterParam3 == '' ? true : filterData.filterParam3.some((filterValue: string) => filterValue.toLowerCase() == data.param3.toLowerCase()));
return find;
}
我已经尝试在.ts代码中的多个不同点更新
this.maxPages
,但无论我把它放在哪里以及在HTML端使用哪个事件,分页器本身总是落后的,我个人不确定如何使用,以及是否有帮助,使用 ._updatePaginator(filteredDataLength: number)
,因为我使用谓词来过滤数据。它过去也不适用于元素,至少对于 (keydown)
和 (input)
事件,因为它们,由于缺乏更好的词,对于分页器来说“太快”,而 (keyup)
则完美地工作。
编辑:经过一些探索后,似乎虽然
this.tableDataSource.Paginator
正在更新,并且在自动完成事件上调用 updateManualPage(1)
之前出现,但出于某种原因 this.maxPages
仍然保持不变。
做
updateMaxPages() {
console.log(this.tableDataSource);
this.maxPages = Math.ceil((this.tableDataSource.paginator?.length ?? 0) / (this.tableDataSource.paginator?.pageSize ?? 1));
}
表明分页器确实正在更新,下一行文字由于某种原因是整个调用后面。
设置超时为0
updateMaxPages() {
setTimeout(() => {
this.maxPages = Math.ceil((this.tableDataSource.paginator?.length ?? 0) / (this.tableDataSource.paginator?.pageSize ?? 1));
})
}
已经“修复”了它,但出于某种原因,我觉得这会在未来产生很多问题。欢迎任何意见!
如果您使用 mat-table 并且不使用 API 进行过滤,则无需使用分页器进行任何操作(材料可以为您提供帮助)。请参阅示例“具有排序、分页和过滤功能的数据表”。在文档
顺便说一句,当你这样做时
this.dataSource.filter = ...
使用
this.dataSource.filter = JSON.stringify(){
param1:form.get('filterParam1').value.toString()
param2:form.get('filterParam2').value.toLowerCase()
param2:form.get('filterParam3').value.toLowerCase()
}
这样你就不需要每次都进行 toLowerCase...
注意:没有毫秒的 setTimeout 会强制 Angular 重新绘制。这是必要的,因为 this.tableDataSource.paginator?.length 在直接执行时没有正确的值并且完全有效(好吧,实际上不是因为它不需要需要手动重新计算。)