3

我正在尝试使用 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 事件而不点击分页

在此处输入图像描述

4

3 回答 3

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
      });
    }
}
于 2016-02-05T19:55:48.647 回答
1

每次page更新组件的属性时实际上都会触发该事件(这可以通过编程方式完成,无需来自 UI 的任何交互)。

实际上,这个事件在初始化pagination组件的时候被触发了 3 次,原因如下:

  • 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在第一次调用结束时将该属性设置为 true writeValue

    writeValue(value:number) {
      this.page = value;
      this.pages = this.getPages(this.page, this.totalPages);
    
      if (!this.inited) {
        this.inited = true;
      }
    }
    

这样,pageChanged事件将在分页初始化阶段仅调用一次。

希望它可以帮助你,蒂埃里

于 2016-01-29T10:01:20.557 回答
0

或者,您可以尝试自定义分页服务而不是 ng2 引导程序,我刚刚发布了这个分页示例,它使用了类似谷歌搜索结果的逻辑。

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>

这篇文章中提供了更多详细信息和工作演示。

于 2016-08-25T00:44:16.257 回答