Mat-autocomplete 和 mat-option 事件在过滤后分页速度太慢?

问题描述 投票:0回答:2

使用我设法从 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));
}

表明分页器确实正在更新,下一行文字由于某种原因是整个调用后面。

javascript angular angular-material pagination
2个回答
1
投票

设置超时为0

updateMaxPages() {
  setTimeout(() => {
    this.maxPages = Math.ceil((this.tableDataSource.paginator?.length ?? 0) / (this.tableDataSource.paginator?.pageSize ?? 1));
  })
}

已经“修复”了它,但出于某种原因,我觉得这会在未来产生很多问题。欢迎任何意见!


0
投票

如果您使用 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 在直接执行时没有正确的值并且完全有效(好吧,实际上不是因为它不需要需要手动重新计算。)

© www.soinside.com 2019 - 2024. All rights reserved.