【问题标题】:Question - Load data paged from Database and still use Pagination from Angular Material问题 - 加载从数据库分页的数据并仍然使用来自 Angular Material 的分页
【发布时间】:2021-07-21 20:38:05
【问题描述】:

我有一个包含 1000 多个条目的表格,我想在 <mat-table></mat-table> 中显示这些条目。

因为我不想一次加载超过一千个条目,所以我想分页加载它们(一次 20 个条目)。

在 "Paginator" 的文档中,它指出,"Paginator" 在加载时需要所有条目。

每个分页器实例都需要: 每页的项目数(默认设置为 50)& 被分页的项目总数

https://material.angular.io/components/paginator/overview

有没有办法在不一次提供所有条目的情况下仍然能够使用 Angular Material Paginator?

提前谢谢你!

【问题讨论】:

    标签: angular typescript angular-material


    【解决方案1】:

    https://material.angular.io/components/paginator/api

    通过上述文档,我们知道每当页面更改时它都会发出一个事件页面。

    最初,当加载数据时,我们只有从服务器获取的第一页行,因此下一页被阻止。因此,在将数据分配给数据源之前,从后端连同当前的行集,还填充可用的总行数并将其设置为长度,这样,mat 分页器的行为就像它拥有所有数据一样。

    简单来说 obj.length = response.total 这将为每个不可用的数据添加一个空值。

    在每个页面事件中,我们都会进行另一个 API 调用并将数据添加到所需的索引中。该事件提供所有必要的数据索引、大小和以前的索引。

    示例参考代码:

    app.component.ts

    import { Component, ViewChild } from '@angular/core';
    
    import { MatTableDataSource } from '@angular/material/table';
    import { MatPaginator, PageEvent } from '@angular/material/paginator';
    import { HttpClient, HttpParams } from '@angular/common/http';
    
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
    
      users: any[];
      loading: boolean = true;
      dataSource = new MatTableDataSource<any>();
    
      title = 'pagination';
    
      @ViewChild(MatPaginator) paginator: MatPaginator;
    
      constructor(private http: HttpClient) {
    
      }
    
      ngOnInit() {
        this.getData('0', '5');
      }
    
      getData(offset, limit){
        let params = new HttpParams();
        params = params.set('offset', offset);
        params = params.set('limit', limit);
    
        this.http.get('http://localhost:3000/users?' + params.toString())
        .subscribe((response: any) =>{
    
          this.loading = false;
          this.users = response.users;
          this.users.length = response.total;
    
          this.dataSource = new MatTableDataSource<any>(this.users);
          this.dataSource.paginator = this.paginator;
    
        })
      }
    
      getNextData(currentSize, offset, limit){
        let params = new HttpParams();
        params = params.set('offset', offset);
        params = params.set('limit', limit);
    
        this.http.get('http://localhost:3000/users?' + params.toString())
        .subscribe((response: any) =>{
    
          this.loading = false;
    
          this.users.length = currentSize;
          this.users.push(...response.users);
    
          this.users.length = response.total;
    
          this.dataSource = new MatTableDataSource<any>(this.users);
          this.dataSource._updateChangeSubscription();
    
          this.dataSource.paginator = this.paginator;
      
        })
      }
    
      pageChanged(event){
        this.loading = true;
    
        let pageIndex = event.pageIndex;
        let pageSize = event.pageSize;
    
        let previousIndex = event.previousPageIndex;
    
        let previousSize = pageSize * pageIndex;
    
        this.getNextData(previousSize, (pageIndex).toString(), pageSize.toString());
      }
    }
    

    getNextData(currentSize, offset, limit) 是您感兴趣的方法。由于我们已经将长度设置为总长度,因此推送其他数据会将其添加到索引之后(将那些空值放在中间)所以我们应该将大小设置回 currentSize 并推送数据并将其大小设置为总大小。

    参考:https://www.bloggernepal.com/2020/04/angular-material-data-table-paginator-with-server-side-pagination.html

    Github 回购链接:https://github.com/InfoDevkota/Server-Side-Pagination-Mat-Paginator

    【讨论】:

    • 谢谢!这是一个非常好的答案,并且有效!
    猜你喜欢
    • 2017-06-12
    • 2014-01-03
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-16
    相关资源
    最近更新 更多