如何封装支持事件与双向绑定的自定义Angular分页组件?
问题修复方案
你的代码存在3处核心问题,修改后即可正常实现双向绑定:
- 模板中
ngb-pagination的pageChange事件未正确绑定处理逻辑,没有把原生组件的页码变更同步到父组件 - 手动输入页码的
selectPage方法修改本地页码后,未向外发射变更事件 - 输入框格式化的正则写法错误,无法正常过滤非数字字符
完整修改后的组件代码
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
相关产品推荐
相关产品推荐

