You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何封装支持事件与双向绑定的自定义Angular分页组件?

问题修复方案

你的代码存在3处核心问题,修改后即可正常实现双向绑定:

  1. 模板中ngb-pagination的pageChange事件未正确绑定处理逻辑,没有把原生组件的页码变更同步到父组件
  2. 手动输入页码的selectPage方法修改本地页码后,未向外发射变更事件
  3. 输入框格式化的正则写法错误,无法正常过滤非数字字符

完整修改后的组件代码

import { Component, Input, Output, OnInit, EventEmitter } from '@angular/core';
import { faChevronLeft, faChevronRight, faAngleDoubleLeft, faAngleDoubleRight } from '@fortawesome/free-solid-svg-icons';

@Component({
  selector: 'app-pagination',
  template: `
    <div class="d-flex justify-content-between p-2">
      <!-- 修改pageChange事件绑定 -->
      <ngb-pagination [collectionSize]="collectionSize" [page]="page" (pageChange)="onPageChange($event)" [pageSize]="pageSize" [boundaryLinks]="true">
        <ng-template ngbPaginationFirst>
          <fa-icon class="fas" [icon]="faAngleDoubleLeft" aria-hidden="true"></fa-icon>
        </ng-template>

        <ng-template ngbPaginationLast>
          <fa-icon class="fas" [icon]="faAngleDoubleRight" aria-hidden="true"></fa-icon>
        </ng-template>

        <ng-template ngbPaginationPages let-page let-pages="pages">
          <li class="ngb-custom-pages-item" *ngIf="pages.length > 0">
              <div class="form-group d-flex flex-nowrap px-2">
                <label id="paginationInputLabel" for="paginationInput" class="col-form-label mr-2 ml-1">Page</label>

                <input #i type="text" inputmode="numeric" pattern="[0-9]*" class="form-control custom-pages-input"
                    id="paginationInput" [value]="page" (keyup.enter)="selectPage(i.value)" (blur)="selectPage(i.value)"
                    (input)="formatInput($any($event).target)" aria-labelledby="paginationInputLabel paginationDescription"
                    style="width: 2.5rem"/>

                <span id="paginationDescription" class="col-form-label text-nowrap px-2">of {{pages.length}}</span>
              </div>
          </li>
        </ng-template>

        <ng-template ngbPaginationPrevious>
          <fa-icon class="fas" [icon]="faChevronLeft" aria-hidden="true"></fa-icon>
        </ng-template>

        <ng-template ngbPaginationNext>
          <fa-icon class="fas" [icon]="faChevronRight" aria-hidden="true"></fa-icon>
        </ng-template>
      </ngb-pagination>
    </div>
  `,
  styleUrls: ['./pagination.component.scss']
})
export class PaginationComponent implements OnInit {
  faChevronLeft = faChevronLeft;
  faChevronRight = faChevronRight;
  faAngleDoubleLeft = faAngleDoubleLeft;
  faAngleDoubleRight = faAngleDoubleRight;

  @Input() collectionSize: number = 20;
  @Input() page: number = 1;
  @Output() pageChange = new EventEmitter<number>();
  @Input() pageSize: number = 10;

  constructor() { }

  ngOnInit(): void {
  }

  // 新增原生分页组件页码变更处理方法
  onPageChange(newPage: number) {
    this.page = newPage;
    this.pageChange.emit(newPage);
  }

  selectPage(page: string) {
    this.page = parseInt(page, 10) || 1;
    // 新增事件发射,同步手动输入的页码到父组件
    this.pageChange.emit(this.page);
  }

  formatInput(input: HTMLInputElement) {
    // 修复正则写法,去掉引号
    input.value = input.value.replace(/[^0-9]/g, '');
  }
}

父组件调用方式无需修改

你原来的双向绑定写法符合Angular规范,[(page)]语法糖会自动对应@Input() page和@Output() pageChange,修改后可以直接正常使用。


内容的提问来源于stack exchange,提问作者Nicke Manarin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 19:57:05