分页只在第一页显示条目

Posted

技术标签:

【中文标题】分页只在第一页显示条目【英文标题】:pagination only showing entries on the first page 【发布时间】:2021-11-20 06:13:51 【问题描述】:

由于包含超过 30k 条目的大量数据,我决定创建一个带有 paginaton 的 mat 表。所以它现在使用我的过滤器工作正常,我唯一的问题是只有第一页显示条目并且页面导航不起作用。所以如果我点击下一页,下一页是空的

这是我的分页器:

  this.persons = data; 
  this.personsFiltered = new MatTableDataSource(this.persons);
  this.personsFiltered.paginator = this.paginator;

FilterChanged() //this filter works with a input field to search for a special name
    this.personsFiltered = of(this.persons).pipe(
      //Name
      map( p => (!this.vornameFilter || this.vornameFilter.trim() === '') ? p: p.filter((i: any) => i.vorname?.toLowerCase().includes(this.vornameFilter.toLowerCase()))),
      
     map(p => p.slice(this.paginator?.pageIndex * this.paginator?.pageSize, this.paginator?.pageSize)) 
    )
  

我的桌子:

<table mat-table [dataSource]="personsFiltered" *ngIf="personsFiltered">

<ng-container matColumnDef="Name">  
                    <th mat-header-cell *matHeaderCellDef  > Name </th>
                    
                    <td mat-cell *matCellDef="let user"> 
                        user.nachname, user.vorname
                    </td>  
                    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>  
                    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator (click)="FilterChanged()" [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>  

为什么不显示其他页面上的条目?

【问题讨论】:

【参考方案1】:
    您错过了lengthpageSize 选项,请将它们提供给mat-paginator,它应该会有所帮助:
<mat-paginator [length]="personsFiltered.data.length" [pageSize]="5" [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
    您还需要在过滤功能中修复分页 - 详情如下。

2a. 修复分页的第一种方法是从函数中删除这部分 (map(p =&gt; p.slice(this.paginator?.pageIndex * this.paginator?.pageSize, this.paginator?.pageSize)) ) 并应用 MatTableDataSoruce - 这是我绝对推荐的,因为它使事情变得更容易,如果你需要,它也可以更容易添加排序和将此排序与过滤相结合。 Angular Material 的文档(https://v5.material.angular.io/components/table/examples - 带分页的表格)中就是一个很好的例子,他们的 Stackblitz 例子在这里:https://stackblitz.com/angular/kbxroarjbeb

您还可以查看此处提供的示例:https://***.com/a/50269705/14556461

在这种方法中,分页由 mat-paginator 自动完成,您的自定义代码会删除应该在下一页显示的数据 - 分页器无法加载更多数据,因为该函数会删除数据。

2b. 另一种方法是更手动地进行分页 - 您可以使用来自mat-paginatorpage 事件,如下所示:

<mat-paginator
  [length]="length"
  [pageSize]="pageSize"
  [pageSizeOptions]="pageSizeOptions"
  (page)="changePage($event)"
>
</mat-paginator>

然后在你的组件中:

changePage(pageEvent: PageEvent) 
  const startIndex = pageEvent.pageIndex * pageEvent.pageSize;
  const endIndex = startIndex + pageEvent.pageSize;
  this.personsFilteredForCurrentPage = this.personsFiltered.slice(startIndex, endIndex);

html 中,只需在 mat-table 中显示 personsFilteredForCurrentPage 而不是 personsFiltered。更新过滤器时更新personsFiltered。这样分页与过滤分离,因此您不必在每次切换页面时过滤所有项目。

当您更改表格中的过滤器时调用FilterChanged()。 您还需要处理更改过滤器/过滤器时发生的情况 - 随着数据的更改,您还需要在过滤器更改后更新 personsFilteredForCurrentPage 以刷新表中的数据。

顺便说一句。这个(click)="FilterChanged()" 在这个地方看起来很奇怪——你确定它应该在这里吗?似乎应该在单击某些按钮或更改输入时调用此函数。无论如何,当您单击分页器时,我会避免调用它。

【讨论】:

感谢您的想法!长度选项让我的表格爆炸,所以我只使用 pageSize 和 PageSizeOptions :D 我还删除了过滤器中的地图线。现在因为我删除了它,它加载了我的所有数据,而不仅仅是 5 个元素。 我更新了我的答案,现在应该更清楚我的意思了,因为以前的版本不够清楚,可能会误导你。请检查我更新的答案,如果有帮助,请告诉我。 好的,所以尝试让 peopleFilteredForCurrentPage 成为 Observable ,就像你之前做的那样。这应该会触发表中的数据刷新,并使您的过滤恢复正常。或者使用自动处理数据刷新的DataSource(例如MatTableDataSource)(您只需像this.dataSource.data = newData一样更新dataSource中的数据,并在表中刷新) 您是否尝试过使用更少的数据?您观察到的错误不应与数据量有关。是否可以在您观察此问题的地方使用您的代码创建 stackblitz?以这种方式帮助您会容易得多。 如果你愿意,你总是可以人为地在 stackblitz 上产生更多的数据(例如,准备生成这么多数据的函数)。不幸的是,如果不了解确切的代码,就无法提供帮助,但我希望您能够与您的朋友一起处理这个问题。如果没有 - 请尝试创建 stackblitz 并在那里人工生成数据。还要确保它确实是由数据量引起的(即尝试减少数据量以进行测试并检查一切是否正常)。更多数据只会让代码变慢,而不是损坏。【参考方案2】:

所以最后我们找到了解决方案。它比我们在这里想的要复杂得多。我们在后端控制器中创建了一个计数方法,如下所示:

 [HttpGet("get/count")]
 public int GetPersonensCount()
 
      return _context.Personens.Count();
 
我们还将 count 方法处理到我的服务和订阅中,如下所示:

getPersonDetails(start: number = 0): Observable<PersonenSharing[]>
    return this.http.get<PersonenSharing[]>(this.pController + start);
  
  
  

getData()
      this.pService.getPersonCount().pipe(
        tap(count => 
          for(let i = 0; i < count; i+=100)
            this.pService.getPersonDetails(i).subscribe(data => 
              if(!this.persons)
                this.persons = [];
                this.personsFiltered = new MatTableDataSource(this.persons);
                this.personsFiltered.paginator = this.paginator;
              
              this.persons = this.persons.concat(data);
              this.FilterChanged();
              if(this.persons.length == count)
                this.loaded = true;
              
            )
          
        )
      ).subscribe();

这就是它的工作原理,目前唯一的问题是性能。

【讨论】:

以上是关于分页只在第一页显示条目的主要内容,如果未能解决你的问题,请参考以下文章

使用 Angular JS 的自定义分页 - 需要在第一页显示 div 元素,这应该在第二页上重复单击下一步

更新数据库条目

PHPMYSQLI实现分页(初学者)

pager分页框架体会

datalist中有分页,如果在第二页删除一条数据,怎么让它刷新后又回到当前页面

oracle分页查询语句怎么写每页查询10条