如何从材料角度使用分页器?

Posted

技术标签:

【中文标题】如何从材料角度使用分页器?【英文标题】:How to use paginator from material angular? 【发布时间】:2018-01-01 06:10:44 【问题描述】:

我是 Angular 新手,正在尝试在我的应用中实现分页。我正在尝试使用this material component.

使用下面的代码,我可以在我的.ts 文件中获得lengthpagesizepageSizeOptions

<md-paginator [length]="length"
              [pageSize]="pageSize"
              [pageSizeOptions]="pageSizeOptions"
</md-paginator>
export class PaginatorConfigurableExample 

  length = 100;
  pageSize = 10;
  pageSizeOptions = [5, 10, 25, 100];

  

但是当页面更改时,我似乎无法触发更改上表数据的函数。另外,我该如何使用nextPagepreviousPagehasNextPagehasPreviousPage方法?

【问题讨论】:

检查此plunker 这可能会有所帮助。对于分页,你也可以使用这个库,我觉得它更简单 [Link](import NgxPaginationModule from "ngx-pagination";)。我用过它here 你确定你发布了正确的 plunker 链接吗? 对不起,但我认为仍然不是正确的 plunker,它打开到plnkr.co/edit/?p=preview 检查它没有保存它plunker 我有兴趣现在是否有更好的解决方案,用于直接处理一些事件,如clicked nextPage? 【参考方案1】:

这对我有用:

确保在 ngOnInit() 中定义数据源(避免ngViewAfterInit 函数中这样做)......像这样

dataSource: MatTableDataSource<Listing> = new MatTableDataSource();
pageEvent: PageEvent;
datasource: null;
pageSizeOptions: number[] = [5, 10, 12, 15];
pageIndex: number;
pageSize: number;
length: number;

constructor(private yourService: YourService) 

ngOnInit() 
   this.dataSource.paginator = this.paginator;
   this.dataSource.sort = this.sort;
   this.pageIndex=0;
   this.pageSize=10;
   this.yourService.getListItems(this.pageSize, 
   this.pageIndex).subscribe(res => 
          this.dataSource.data = res;
          this.lenght=res.lenght();
       );
     
handlePageEvent(event: PageEvent) 
   this.yourService.getListItems(event.pageSize, 
   event.pageIndex).subscribe(e=>
     this.dataSource.data = res;
);       
return event;


 

你的html组件是这样的

 <mat-paginator (page)="handlePageEvent($event)"
      [pageSizeOptions]="pageSizeOptions"
      [pageSize]="pageSize"
      class="sticky left-0"
      [length]="length"
      [pageIndex]="pageIndex"
      aria-label="Select page"
  ></mat-paginator>

【讨论】:

【参考方案2】:

根据 Wesley Coetzee 的回答,我写了这个。希望它可以帮助任何人在谷歌上搜索这个问题。我在列表中间交换分页器大小时遇到​​了错误,这就是我提交答案的原因:

分页器 html 和列表

<mat-paginator [length]="localNewspapers.length" pageSize=20
               (page)="getPaginatorData($event)" [pageSizeOptions]="[10, 20, 30]"
               showFirstLastButtons="false">
</mat-paginator>
<mat-list>
   <app-newspaper-pagi-item *ngFor="let paper of (localNewspapers | 
                         slice: lowValue : highValue)"
                         [newspaper]="paper"> 
  </app-newspaper-pagi-item>

组件逻辑

import Component, Input, OnInit from "@angular/core";
import PageEvent from "@angular/material";

@Component(
  selector: 'app-uniques-newspaper-list',
  templateUrl: './newspaper-uniques-list.component.html',
)
export class NewspaperUniquesListComponent implements OnInit 
  lowValue: number = 0;
  highValue: number = 20;

  // used to build a slice of papers relevant at any given time
  public getPaginatorData(event: PageEvent): PageEvent 
    this.lowValue = event.pageIndex * event.pageSize;
    this.highValue = this.lowValue + event.pageSize;
    return event;
  


【讨论】:

感谢工作! Angular 9 使用此导入代替 -----> import PageEvent from '@angular/material/paginator'; 这是最简单的例子,值得尊敬。 干得好!谢谢 到目前为止最好的答案,谢谢【参考方案3】:

我在这里也遇到了同样的问题。但我可以向你展示我所做的一些研究。 基本上,您首先开始在 foo.template.ts 中添加页面 @Output 事件:

 <md-paginator #paginator
                [length]="length"
                [pageIndex]="pageIndex"
                [pageSize]="pageSize"
                [pageSizeOptions]="[5, 10, 25, 100]"
                (page)="pageEvent = getServerData($event)"
                >
 </md-paginator>

然后,您必须在 foo.component.ts 类和其他类中添加 pageEvent 属性来处理分页器要求:

pageEvent: PageEvent;
datasource: null;
pageIndex:number;
pageSize:number;
length:number;

并添加将获取服务器数据的方法:

ngOnInit() 
   getServerData(null) ...


public getServerData(event?:PageEvent)
  this.fooService.getdata(event).subscribe(
    response =>
      if(response.error) 
        // handle error
       else 
        this.datasource = response.data;
        this.pageIndex = response.pageIndex;
        this.pageSize = response.pageSize;
        this.length = response.length;
      
    ,
    error =>
      // handle error
    
  );
  return event;

因此,基本上,每次单击分页器时,都会激活 getServerData(..) 方法,该方法将调用 foo.service.ts 获取所需的所有数据。在这种情况下,您不需要处理 nextPagenextXXX 事件,因为它们会在视图渲染时自动计算。

我希望这可以帮助你。让我知道你是否成功。 =]

【讨论】:

我没有触发(页面)事件。 可以滚动而不是点击页面吗? 投票,谢谢。但是在分页之后,mat-checkbox 无法设置检查,即使我以编程方式设置它。有什么想法吗? 您在模板代码中分配的 pageEvent 属性不会在任何地方使用。它有目的吗? html 文件中将(page)="pageEvent = getServerData($event)" 替换为(page)="getServerData($event)"【参考方案4】:

这里的棘手部分是处理页面事件。 我们可以按照角度材料文档定义页面事件函数。

访问https://material.angular.io/components/paginator/examples 供参考。

我将在这方面付出数小时的辛勤工作。 在相关的 HTML 文件中应该如下所示,

<pre>
<mat-paginator
    [pageSizeOptions]="pageSizeOptions"
    [pageSize]="Size"
    (page)="pageEvent = pageNavigations($event)"
    [length]="recordCount">
</mat-paginator>
</pre>

然后转到相关的打字稿文件和以下代码,

声明,

@Input('data') customers: Observable<Customer[]>;
pageEvent: PageEvent;
Page: number=0;
Size: number=2;
recordCount: number;
pageSizeOptions: number[] = [2,3,4,5];

页面导航的关键部分如下,

pageNavigations(event? : PageEvent)
    console.log(event);
    this.Page = event.pageIndex;
    this.Size = event.pageSize;
    this.reloadData();
  

我们需要以下函数从后端调用数据。

reloadData() 

    this.customers = this.customerService.setPageSize(this.Page ,this.Size);
    this.customerService.getSize().subscribe(res => 
      this.recordCount = Number(res);
     
      console.log(this.recordCount);
    );
  

在上述实现之前,我们的服务文件应该包含以下服务调用

setPageSize(page: number, size: number): Observable<any> 
    return this.http.get(`$this.baseUrl?pageSize=$size&pageNo=$page`);
  

然后一切就绪,在我们的应用中启用分页。请随时提出相关问题谢谢。

【讨论】:

【参考方案5】:

花了几个小时后,这个问题得到了解决,我让它工作了。这被认为是用角材料解决分页的最简单方法。 - 首先从处理(component.html)文件开始

 <mat-paginator [pageSizeOptions]="[2, 5, 10, 15, 20]" showFirstLastButtons>
 </mat-paginator>

在(component.ts)文件中做

 import  MatPaginator  from '@angular/material/paginator';
 import  Component, OnInit, ViewChild  from '@angular/core';

 export interface UserData 
 full_name: string;
 email: string;
 mob_number: string;
 

 export class UserManagementComponent implements OnInit
  dataSource : MatTableDataSource<UserData>;

  @ViewChild(MatPaginator) paginator: MatPaginator;

  constructor()
    this.userList();
   

    ngOnInit()  

   public userList() 

   this._userManagementService.userListing().subscribe(
      response => 

      console.log(response['results']);
      this.dataSource = new MatTableDataSource<UserData>(response['results']);
      this.dataSource.paginator = this.paginator;
      console.log(this.dataSource);

     ,


      error => );

     

 

记住必须在您当前工作的模块(module.ts)文件中导入分页模块。

  import MatPaginatorModule from '@angular/material/paginator';

   @NgModule(
      imports: [MatPaginatorModule]
    )

希望它对你有用。

【讨论】:

【参考方案6】:

另一种使用 Slice Pipe 将 Angular Paginator 与数据表链接的方法。这里的数据只从服务器获取一次。

查看:

 <div class="col-md-3" *ngFor="let productObj of productListData | 
     slice: lowValue : highValue">
       //actual data dispaly  
 </div>

<mat-paginator [length]="productListData.length" [pageSize]="pageSize" 
   (page)="pageEvent = getPaginatorData($event)">
</mat-paginator> 

组件

    pageIndex:number = 0;
    pageSize:number = 50;
    lowValue:number = 0;
    highValue:number = 50;       

  getPaginatorData(event)
     console.log(event);
     if(event.pageIndex === this.pageIndex + 1)
        this.lowValue = this.lowValue + this.pageSize;
        this.highValue =  this.highValue + this.pageSize;
       
    else if(event.pageIndex === this.pageIndex - 1)
       this.lowValue = this.lowValue - this.pageSize;
       this.highValue =  this.highValue - this.pageSize;
         
       this.pageIndex = event.pageIndex;
 

【讨论】:

不错,如果您只想要客户端分页。帮助过我。谢谢@Asridh 这个例子没有完全回答原始问题。最初的问题包括 pageSizeOptions,这个例子忽略了它。对于未来的读者,我通过包含以下内容来处理这个问题:this.highValue = this.highValue + event.pageSize - this.pageSize; this.pageSize = event.pageSize;仍然对原始帖子进行投票,因为它超级快速/简单,并且无论您是否使用 MatTable 都可以正常工作,许多其他答案都假设这一点。【参考方案7】:

组件:

import  Component,  AfterViewInit, ViewChild  from @angular/core;
import  MatPaginator  from @angular/material;

export class ClassName implements AfterViewInit 
    @ViewChild(MatPaginator) paginator: MatPaginator;
    length = 1000;
    pageSize = 10;
    pageSizeOptions: number[] = [5, 10, 25, 100];

    ngAfterViewInit() 
        this.paginator.page.subscribe(
           (event) => console.log(event)
    );

HTML

<mat-paginator 
   [length]="length"
   [pageSize]="pageSize" 
   [pageSizeOptions]="pageSizeOptions"
   [showFirstLastButtons]="true">
</mat-paginator>

【讨论】:

【参考方案8】:

原始问题中的问题是您没有捕获“页面”事件,要解决此问题,您需要在 md-paginator 标记中添加 (page)='yourEventHandler($event)' 作为属性。

检查一个工作示例here

您也可以查看 API 文档here

【讨论】:

不推荐格式错误的主要链接答案。【参考方案9】:

在花了几个小时之后,我认为这是应用分页的最佳方式。更重要的是它有效。 这是我的分页器代码 &lt;mat-paginator #paginatoR [length]="length" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions"&gt;

在我的组件@ViewChild(MatPaginator) paginator: MatPaginator; 中查看子组件,最后您必须将分页器绑定到表数据源,这就是它的完成方式 ngAfterViewInit() this.dataSource.paginator = this.paginator; 容易吧?如果它对您有用,请将其标记为答案。

【讨论】:

【参考方案10】:

嘿,所以我偶然发现了这个并让它工作了,方法如下:

在我的 component.html

<mat-paginator #paginator [pageSize]="pageSize" [pageSizeOptions]="[5, 10, 20]" [showFirstLastButtons]="true" [length]="totalSize"
    [pageIndex]="currentPage" (page)="pageEvent = handlePage($event)">
</mat-paginator>

在我的 component.ts

public array: any;
public displayedColumns = ['', '', '', '', ''];
public dataSource: any;    

public pageSize = 10;
public currentPage = 0;
public totalSize = 0;

@ViewChild(MatPaginator) paginator: MatPaginator;

constructor(private app: AppService)  

ngOnInit() 
  this.getArray();


public handlePage(e: any) 
  this.currentPage = e.pageIndex;
  this.pageSize = e.pageSize;
  this.iterator();


private getArray() 
  this.app.getDeliveries()
    .subscribe((response) => 
      this.dataSource = new MatTableDataSource<Element>(response);
      this.dataSource.paginator = this.paginator;
      this.array = response;
      this.totalSize = this.array.length;
      this.iterator();
    );


private iterator() 
  const end = (this.currentPage + 1) * this.pageSize;
  const start = this.currentPage * this.pageSize;
  const part = this.array.slice(start, end);
  this.dataSource = part;

所有的分页工作都是在iterator 方法中完成的。此方法计算出 skiptake 并将其分配给 Material 表的 dataSource

【讨论】:

您需要将 pageEvent 声明为属性 ( pageEvent: PageEvent; ) 否则它将仅在开发模式下运行 (ng serve) 而不是在生产模式下 (ng build configuration=production)。生产有更多限制,编译器会抱怨你的组件缺少 pageEvent 属性。 如果没有检索到数据怎么办(如 404、400 和此类 http 错误)?如果它的服务器端分页:等待加载服务器数据呢?如果您单击下一页 x 次,并且 UI 检索数据的速度不够快,则分页器可能会出现故障或延迟显示所需的页面数据。 您必须使用pipe() 来捕获错误并处理这种情况

以上是关于如何从材料角度使用分页器?的主要内容,如果未能解决你的问题,请参考以下文章

具有垫表初始化的角度材料2分页器

如何使用材料角的分页器?

自定义角材料分页器输入

角材料分页器不工作

分页在角度 7 中不起作用。(我使用角度材料)

单页分页问题中的多个角度材料表