如何从材料角度使用分页器?
Posted
技术标签:
【中文标题】如何从材料角度使用分页器?【英文标题】:How to use paginator from material angular? 【发布时间】:2018-01-01 06:10:44 【问题描述】:我是 Angular 新手,正在尝试在我的应用中实现分页。我正在尝试使用this material component.
使用下面的代码,我可以在我的.ts
文件中获得length
、pagesize
和pageSizeOptions
<md-paginator [length]="length"
[pageSize]="pageSize"
[pageSizeOptions]="pageSizeOptions"
</md-paginator>
export class PaginatorConfigurableExample
length = 100;
pageSize = 10;
pageSizeOptions = [5, 10, 25, 100];
但是当页面更改时,我似乎无法触发更改上表数据的函数。另外,我该如何使用nextPage
、previousPage
、hasNextPage
和hasPreviousPage
方法?
【问题讨论】:
检查此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 获取所需的所有数据。在这种情况下,您不需要处理 nextPage 和 nextXXX 事件,因为它们会在视图渲染时自动计算。
我希望这可以帮助你。让我知道你是否成功。 =]
【讨论】:
我没有触发(页面)事件。 可以滚动而不是点击页面吗? 投票,谢谢。但是在分页之后,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】:在花了几个小时之后,我认为这是应用分页的最佳方式。更重要的是它有效。
这是我的分页器代码
<mat-paginator #paginatoR [length]="length" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions">
在我的组件@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
方法中完成的。此方法计算出 skip
和 take
并将其分配给 Material 表的 dataSource
。
【讨论】:
您需要将 pageEvent 声明为属性 ( pageEvent: PageEvent; ) 否则它将仅在开发模式下运行 (ng serve) 而不是在生产模式下 (ng build configuration=production)。生产有更多限制,编译器会抱怨你的组件缺少 pageEvent 属性。 如果没有检索到数据怎么办(如 404、400 和此类 http 错误)?如果它的服务器端分页:等待加载服务器数据呢?如果您单击下一页 x 次,并且 UI 检索数据的速度不够快,则分页器可能会出现故障或延迟显示所需的页面数据。 您必须使用pipe()
来捕获错误并处理这种情况以上是关于如何从材料角度使用分页器?的主要内容,如果未能解决你的问题,请参考以下文章