web-dev-qa-db-ja.com

ngx-datatableを使用してサーバー側のページ付け+サーバー側の並べ替えを実装する方法

Angular component ngx-datatable from Swilane with server-side paging and サーバー側の並べ替え

両方とも文書化されていますが、それらを組み合わせてサーバー側のページ付けと並べ替えを同時に使用する方法は明確ではありません

ドキュメントから、ユーザーがページを変更すると、ページネーションは自動的にコールバックを呼び出します。

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);
  }

しかし、それらをどのように組み合わせるのですか?

6
Francesco Borzi

サーバー側のページ付けとサーバー側の並べ替えの両方を処理する最良の方法は、次のもので構成されていることがわかりました。

  • テーブルにバインドされるすべてのページ付けおよび並べ替え情報(注文列、注文方向、ページ番号、ページサイズなど)を保持するpageオブジェクトを持っている

  • 単一の関数reloadTable()を持ち、APIを呼び出して、pageオブジェクトに格納されているデータをパラメーターとして使用してデータを取得し、テーブルを自動的に再レン​​ダリングします。

  • のみpageCallbackに含まれるデータをページネーションに関連して更新し、reloadTable()を呼び出すpageを持つ

  • sortCallbackを持っているのみpageに含まれるデータをsortingに関連して更新し、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;
      });
  }
}
13
Francesco Borzi