我正在尝试使用ng2-bootrap在我的angular2应用程序中实现分页。我正在关注http://valor-software.github.io/ng2-bootstrap/#pagination
我的 app.html
<div>
<div class="col-lg-12 text-right">
<pagination [totalItems]="totalItems" [itemsPerPage]='2' (pageChanged)="pageChanged($event)" [(ngModel)]="currentPage" [maxSize]="maxSize"
class="pagination-sm" [boundaryLinks]="true"></pagination>
</div>
</div>
我的组件
import { Component, View, Inject} from 'angular2/core';
import { CORE_DIRECTIVES } from 'angular2/common';
import { PAGINATION_COMPONENTS } from 'ng2-bootstrap/ng2-bootstrap';
// webpack html imports
@View({
templateUrl: '/scripts/src/components/demo/demo.html',
directives: [PAGINATION_COMPONENTS, CORE_DIRECTIVES]
})
@Component({
selector: 'tabs-demo',
})
export class DemoComponent {
private totalItems: number = 64;
private currentPage: number = 4;
private maxSize: number = 5;
private bigTotalItems: number = 175;
private bigCurrentPage: number = 1;
private setPage(pageNo: number): void {
this.currentPage = pageNo;
};
private pageChanged(event: any): void {
console.log('Page changed to: ' + event.page);
console.log('Number items per page: ' + event.itemsPerPage);
};
}
多次触发pageChange事件而不点击分页
答案 0 :(得分:1)
每次更新组件的page
属性时都会触发事件(这可以通过编程方式完成,而无需来自UI的任何交互)。
事实上,由于以下原因,在初始化pagination
组件时会触发此事件三次:
ngInit
方法的。这是组件生命周期的一部分。
export class Pagination implements ControlValueAccessor, OnInit, IPaginationConfig, IAttribute {
(...)
ngOnInit() {
(...)
this.page = this.cd.value;
(...)
}
(...)
}
writeValue
方法的 。调用此方法是因为该组件符合ngModel标准。更新ngModel
中关联的表达式后,将使用新值调用此方法。在初始化期间,writeValue
方法被调用两次:首先使用null
值,然后使用1
值。
export class Pagination implements ControlValueAccessor, OnInit, IPaginationConfig, IAttribute {
(...)
writeValue(value:number) {
this.page = value;
this.pages = this.getPages(this.page, this.totalPages);
}
(...)
}
也就是说,在此初始化阶段之后,pageChanged
仅在每page
次更新时触发一次。
修改强>
看了ng2-bootstrap的代码之后,如果不更新Pagination组件的代码,我就看不出怎么做。
以下是您可以在此课程中执行的更新(文件node_modules/ng2-bootstrap/components/pagination/pagination.ts
):
仅当set page
属性为inited
时才更新true
块以触发事件:
public set page(value) {
this._page = (value > this.totalPages) ? this.totalPages : (value || 1);
if (this.inited) { // <---------------
this.pageChanged.next({
page: this._page,
itemsPerPage: this.itemsPerPage
});
}
}
更新ngOnInit
方法,不要将inited
属性设置为true:
ngOnInit() {
(...)
//this.inited = true;
}
在inited
的第一次调用结束时将writeValue
属性设置为true:
writeValue(value:number) {
this.page = value;
this.pages = this.getPages(this.page, this.totalPages);
if (!this.inited) {
this.inited = true;
}
}
这样,pageChanged
事件在分页初始化阶段只会被调用一次。
希望它可以帮到你, 亨利
答案 1 :(得分:1)
如果您只想在用户点击分页时触发'pageChanged'事件,您可以将设置页面块更改为:
public set page(value) {
var _previous = this._page;
this._page = (value > this.totalPages) ? this.totalPages : (value || 1);
if (_previous !== this._page && typeof _previous !== 'undefined') {
this.pageChanged.emit({
page: this._page,
itemsPerPage: this.itemsPerPage
});
}
}
答案 2 :(得分:0)
或者您可以尝试使用自定义分页服务而不是ng2 bootstrap,我刚刚发布了this pagination example,它使用谷歌搜索结果等逻辑。
处理分页逻辑的PagerService :
import * as _ from 'underscore';
export class PagerService {
getPager(totalItems: number, currentPage: number = 1, pageSize: number = 10) {
// calculate total pages
var totalPages = Math.ceil(totalItems / pageSize);
var startPage, endPage;
if (totalPages <= 10) {
// less than 10 total pages so show all
startPage = 1;
endPage = totalPages;
} else {
// more than 10 total pages so calculate start and end pages
if (currentPage <= 6) {
startPage = 1;
endPage = 10;
} else if (currentPage + 4 >= totalPages) {
startPage = totalPages - 9;
endPage = totalPages;
} else {
startPage = currentPage - 5;
endPage = currentPage + 4;
}
}
// calculate start and end item indexes
var startIndex = (currentPage - 1) * pageSize;
var endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);
// create an array of pages to ng-repeat in the pager control
var pages = _.range(startPage, endPage + 1);
// return object with all pager properties required by the view
return {
totalItems: totalItems,
currentPage: currentPage,
pageSize: pageSize,
totalPages: totalPages,
startPage: startPage,
endPage: endPage,
startIndex: startIndex,
endIndex: endIndex,
pages: pages
};
}
}
使用寻呼机服务的AppComponent :
import { Component, OnInit } from '@angular/core';
import * as _ from 'underscore';
import { PagerService } from './_services/index'
@Component({
moduleId: module.id,
selector: 'app',
templateUrl: 'app.component.html'
})
export class AppComponent {
constructor(private pagerService: PagerService) { }
// dummy array of items to be paged
private dummyItems = _.range(1, 151);
// pager object
pager: any = {};
// paged items
pagedItems: any[];
ngOnInit() {
// initialize to page 1
this.setPage(1);
}
setPage(page: number) {
if (page < 1) {
return;
}
// get pager object from service
this.pager = this.pagerService.getPager(this.dummyItems.length, page);
// get current page of items
this.pagedItems = this.dummyItems.slice(this.pager.startIndex, this.pager.endIndex + 1);
}
}
AppComponent HTML ,显示分页项和寻呼机控件:
<div>
<div class="container">
<div class="text-center">
<h1>Angular 2 - Pagination Example with logic like Google</h1>
<!-- items being paged -->
<div *ngFor="let item of pagedItems">Item {{item}}</div>
<!-- pager -->
<ul *ngIf="pager.pages.length" class="pagination">
<li [ngClass]="{disabled:pager.currentPage === 1}">
<a (click)="setPage(1)">First</a>
</li>
<li [ngClass]="{disabled:pager.currentPage === 1}">
<a (click)="setPage(pager.currentPage - 1)">Previous</a>
</li>
<li *ngFor="let page of pager.pages" [ngClass]="{active:pager.currentPage === page}">
<a (click)="setPage(page)">{{page}}</a>
</li>
<li [ngClass]="{disabled:pager.currentPage === pager.totalPages}">
<a (click)="setPage(pager.currentPage + 1)">Next</a>
</li>
<li [ngClass]="{disabled:pager.currentPage === pager.totalPages}">
<a (click)="setPage(pager.totalPages)">Last</a>
</li>
</ul>
</div>
</div>
</div>
this post上提供了更多详细信息和工作演示。