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

如何为Angular ngx-datatable添加自定义分页器模板

解决ngx-datatable自定义分页器不显示的问题

你遇到的核心问题是:datatable-pager组件本身并不支持传入自定义模板替换内部结构,它的渲染逻辑是固定封装的,你添加的<ng-template>不会被组件识别和使用,所以页面依然显示默认样式。下面给你两种适配需求的解决方案:


方案1:快速替换图标(适合仅替换FontAwesome箭头的场景)

如果你的需求只是把默认箭头换成FontAwesome图标,不用完全重写分页器,ngx-datatable已经提供了图标类名的输入属性,直接配置即可:

  1. 确保项目已正确引入FontAwesome(npm安装+angular.json配置,或CDN引入)
  2. 修改datatable-pager的图标属性,替换为FontAwesome的类名:
<datatable-pager 
  #ngxDatatablePager 
  [pagerLeftArrowIcon]="'fas fa-chevron-left'"  <!-- 上一页箭头 -->
  [pagerRightArrowIcon]="'fas fa-chevron-right'" <!-- 下一页箭头 -->
  [pagerPreviousIcon]="'fas fa-angle-double-left'" <!-- 跳转到第一页 -->
  [pagerNextIcon]="'fas fa-angle-double-right'" <!-- 跳转到最后一页 -->
  [page]="curPage" 
  [size]="pageSize" 
  [count]="rowCount" 
  [hidden]="!((rowCount / pageSize) > 1)" 
  (change)="ngxDatatable.onFooterPage($event)"
></datatable-pager>

这种方式无需自定义模板,直接复用内置分页器的逻辑,只替换图标,简单高效。


方案2:完全自定义分页器(适合需要深度样式/功能调整)

如果需要修改分页布局、添加额外功能,那就放弃内置的datatable-pager,自己在footer模板里实现分页逻辑:

第一步:组件类中添加分页相关逻辑

// 组件.ts文件
import { Component, ViewChild, SimpleChanges } from '@angular/core';
import { DatatableComponent } from '@swimlane/ngx-datatable';

@Component({
  // 组件元数据
})
export class YourComponent {
  @ViewChild('ngxDatatable') ngxDatatable!: DatatableComponent;
  
  curPage: number = 1;
  pageSize: number = 2;
  totalRows: number = 0;
  // 你的其他变量:files、fileNameLikeDataContract、searchTags等

  // 监听数据变化,更新总行数
  ngOnChanges(changes: SimpleChanges) {
    if (changes.files) {
      this.totalRows = (this.files | objectPropertyLikeStringPipe:this.fileNameLikeDataContract | objectHasTagPipe:this.searchTags:'tags').length;
    }
  }

  // 分页核心方法
  goToPage(page: number) {
    if (page < 1 || page > this.totalPages) return;
    this.curPage = page;
    // 通知datatable切换页面
    this.ngxDatatable.page({ offset: page - 1 });
  }

  prevPage() {
    this.goToPage(this.curPage - 1);
  }

  nextPage() {
    this.goToPage(this.curPage + 1);
  }

  // 计算总页数
  get totalPages(): number {
    return Math.ceil(this.totalRows / this.pageSize);
  }

  // 生成显示的页码列表(比如当前页前后各2页)
  get pages(): Array<{number: number, text: string}> {
    const pages = [];
    const start = Math.max(1, this.curPage - 2);
    const end = Math.min(this.totalPages, this.curPage + 2);
    for (let i = start; i <= end; i++) {
      pages.push({ number: i, text: i.toString() });
    }
    return pages;
  }
}

第二步:模板中替换为自定义分页UI

去掉内置的datatable-pager,直接在footer模板里写自定义分页结构:

<ngx-datatable 
  #ngxDatatable
  *ngIf="(files | objectPropertyLikeStringPipe:fileNameLikeDataContract | objectHasTagPipe:searchTags:'tags').length" 
  class="classic show-overflow" 
  bbsNgxResizeWatcher 
  [rowHeight]="undefined" 
  [columnMode]="'flex'" 
  (activate)="tableActivate($event)" 
  [rows]="files | objectPropertyLikeStringPipe:fileNameLikeDataContract | objectHasTagPipe:searchTags:'tags'" 
  [sorts]="[{prop:'type',dir:'asc'},{prop:'fileName',dir:'asc'}]" 
  [columns]="columns" 
  [selected]="selected" 
  [selectionType]="'checkbox'" 
  (select)="onSelect($event)" 
  [limit]="pageSize" 
  [footerHeight]="50"
  (page)="curPage = $event.offset + 1" <!-- 监听datatable分页事件,同步当前页 -->
> 
  <ngx-datatable-footer> 
    <ng-template 
      ngx-datatable-footer-template 
      let-rowCount="rowCount" 
      let-pageSize="pageSize" 
      let-selectedCount="selectedCount" 
      let-curPage="curPage" 
      let-offset="offset" 
      let-isVisible="isVisible"
    > 
      <div class="page-count"> 
        <span *ngIf="selectedMessage"> 
          {{selectedCount.toLocaleString()}} {{selectedMessage}} / 
        </span> 
        {{rowCount.toLocaleString()}} {{totalMessage}} 
      </div>

      <!-- 自定义分页器 -->
      <ul class="pager" *ngIf="totalPages > 1">
        <li [class.disabled]="curPage === 1">
          <a role="button" aria-label="go to first page" href="javascript:void(0)" (click)="prevPage()">
            <fa-icon [icon]="['fal', 'angle-left']"></fa-icon>
          </a>
        </li>
        <li [class.disabled]="curPage === 1">
          <a role="button" aria-label="go to previous page" href="javascript:void(0)" (click)="goToPage(curPage - 1)">
            <fa-icon [icon]="['fal', 'chevron-left']"></fa-icon>
          </a>
        </li>
        <li 
          role="button" 
          [attr.aria-label]="'page ' + pg.number" 
          class="pages" 
          *ngFor="let pg of pages" 
          [class.active]="pg.number === curPage"
        >
          <a href="javascript:void(0)" (click)="goToPage(pg.number)">
            {{pg.text}}
          </a>
        </li>
        <li [class.disabled]="curPage === totalPages">
          <a role="button" aria-label="go to next page" href="javascript:void(0)" (click)="goToPage(curPage + 1)">
            <fa-icon [icon]="['fal', 'chevron-right']"></fa-icon>
          </a>
        </li>
        <li [class.disabled]="curPage === totalPages">
          <a role="button" aria-label="go to last page" href="javascript:void(0)" (click)="goToPage(totalPages)">
            <fa-icon [icon]="['fal', 'angle-right']"></fa-icon>
          </a>
        </li>
      </ul>
    </ng-template> 
  </ngx-datatable-footer> 
</ngx-datatable>

第三步:添加自定义样式(可选)

根据需要编写CSS调整分页器的外观,比如按钮间距、选中状态样式等。


内容的提问来源于stack exchange,提问作者Karl Johan Vallner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:42:00