【问题标题】: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?

标签: angular pagination angular-material


【解决方案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() 来捕获错误并处理这种情况
            猜你喜欢
            • 2019-06-20
            • 2018-11-21
            • 1970-01-01
            • 1970-01-01
            • 2020-04-19
            • 2020-04-23
            • 2020-04-26
            • 2018-05-30
            • 2018-05-26
            相关资源
            最近更新 更多