如何使用 ngx-datatable 实现服务端分页+服务端排序

Posted

技术标签:

【中文标题】如何使用 ngx-datatable 实现服务端分页+服务端排序【英文标题】:How to implement server-side Pagination + server-side Sorting with ngx-datatable 【发布时间】:2018-02-12 20:53:21 【问题描述】:

使用来自Swilane 的Angular 组件ngx-datatable,可以使用server-side paging 和server-side sorting。

两者都有文档,但不清楚如何组合它们并同时使用服务器端分页+排序

从文档来看,分页会在用户切换页面时自动调用回调:

setPage(pageInfo) 
    this.page.pageNumber = pageInfo.offset;
    this.serverResultsService.getResults(this.page).subscribe(pagedData => 
    this.page = pagedData.page;
    this.rows = pagedData.data;
 );

排序也是如此:

onSort(event) 
    // event was triggered, start sort sequence
    console.log('Sort Event', event);
    this.loading = true;
    // emulate a server request with a timeout
    setTimeout(() => 
      const rows = [...this.rows];
      // this is only for demo purposes, normally
      // your server would return the result for
      // you and you would just set the rows prop
      const sort = event.sorts[0];
      rows.sort((a, b) => 
        return a[sort.prop].localeCompare(b[sort.prop]) * (sort.dir === 'desc' ? -1 : 1);
      );

      this.rows = rows;
      this.loading = false;
    , 1000);
  

但是如何组合它们呢?

【问题讨论】:

【参考方案1】:

我发现处理服务器端分页和服务器端排序的最佳方法包括:

拥有一个page 对象,该对象包含将绑定到表格的所有分页和排序信息(如订单列、订单方向、页码、页面大小...)

具有单个函数reloadTable(),它调用API以使用存储在page对象中的数据作为参数获取数据,自动重新渲染表格

有一个pageCallback,它更新page中相对于分页的数据,然后调用reloadTable()

有一个sortCallback,它相对于排序更新page中包含的数据,然后调用reloadTable()

示例:

import  Component, OnInit  from '@angular/core';
import  HttpClient, HttpParams  from '@angular/common/http';

@Component(
  selector: 'app-my-component',
  template: `
    <ngx-datatable
      class="bootstrap table table-striped"
      [rows]="rows"
      [columns]="columns"
      [columnMode]="'force'"
      [headerHeight]="50"
      [footerHeight]="50"
      [rowHeight]="'auto'"
      [externalPaging]="true"
      [externalSorting]="true"
      [count]="page.count"
      [offset]="page.offset"
      [limit]="page.limit"
      [sortType]="'single'"
      (page)="pageCallback($event)"
      (sort)="sortCallback($event)"
    ></ngx-datatable>
  `
)
export class MyComponent implements OnInit 
  page = 
    limit: 10,
    count: 0,
    offset: 0,
    orderBy: 'myColumn1',
    orderDir: 'desc'
  ;

  rows: Object[];

  columns = [
     name: 'myColumn1' ,
     name: 'myColumn2' ,
     name: 'myColumn3' ,
  ];

  constructor(private httpClient: HttpClient)  

  ngOnInit() 
    this.pageCallback( offset: 0 );
  

  /**
   * Called whenever the user changes page
   *
   * check: https://swimlane.gitbooks.io/ngx-datatable/content/api/table/outputs.html
   */
  pageCallback(pageInfo:  count?: number, pageSize?: number, limit?: number, offset?: number ) 
    this.page.offset = pageInfo.offset;
    this.reloadTable();
  

  /**
   * Called whenever the user changes the sort order
   *
   * check: https://swimlane.gitbooks.io/ngx-datatable/content/api/table/outputs.html
   */
  sortCallback(sortInfo:  sorts:  dir: string, prop: string [], column: , prevValue: string, newValue: string ) 
    // there will always be one "sort" object if "sortType" is set to "single"
    this.page.orderDir = sortInfo.sorts[0].dir;
    this.page.orderBy = sortInfo.sorts[0].prop;
    this.reloadTable();
  

  /**
   * You will render the table once at the beginning in ngOnInit()
   * and then every time the page OR the sort order are changed
   */
  reloadTable() 

    // NOTE: those params key values depends on your API!
    const params = new HttpParams()
      .set('orderColumn', `$this.page.orderBy`)
      .set('orderDir', `$this.page.orderDir`)
      .set('pageNumber', `$this.page.offset`)
      .set('pageSize', `$this.page.limit`);

    this.httpClient.get(`http://www.your-api.com/path/resource`,  params )
      .subscribe((data) => 

        // NOTE: the format of the returned data depends on your API!
        this.page.count = data.count;
        this.rows = data.rows;
      );
  

【讨论】:

以上是关于如何使用 ngx-datatable 实现服务端分页+服务端排序的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Datatable 以 POST 类型传递请求正文数据以使用 Javascript 进行服务器端分页

如何在引导表中使用带有 ajax 的服务器端分页?

如何使用 NestJS 提供服务器端分页?

使用 ngx-pagination 的服务器端分页

用DataTables实现服务器端分页

使用wenzhixin引导表服务器端分页时如何向td元素添加类或属性