2017-12-18 13 views
4

角度材質2、MatPaginatorサーバー側のページングを達成しようとしています。どうすれば達成できますか?角度材質2テーブルサーバー側のページ番号

以下

コードの例です:

<div class="example-container mat-elevation-z8"> 
    <mat-table #table [dataSource]="dataSource"> 

    <!-- Position Column --> 
    <ng-container matColumnDef="position"> 
     <mat-header-cell *matHeaderCellDef> No. </mat-header-cell> 
     <mat-cell *matCellDef="let element"> {{element.position}} </mat-cell> 
    </ng-container> 

    <!-- Name Column --> 
    <ng-container matColumnDef="name"> 
     <mat-header-cell *matHeaderCellDef> Name </mat-header-cell> 
     <mat-cell *matCellDef="let element"> {{element.name}} </mat-cell> 
    </ng-container> 

    <!-- Weight Column --> 
    <ng-container matColumnDef="weight"> 
     <mat-header-cell *matHeaderCellDef> Weight </mat-header-cell> 
     <mat-cell *matCellDef="let element"> {{element.weight}} </mat-cell> 
    </ng-container> 

    <!-- Symbol Column --> 
    <ng-container matColumnDef="symbol"> 
     <mat-header-cell *matHeaderCellDef> Symbol </mat-header-cell> 
     <mat-cell *matCellDef="let element"> {{element.symbol}} </mat-cell> 
    </ng-container> 

    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> 
    <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row> 
    </mat-table> 

    <mat-paginator #paginator 
       [pageSize]="10" 
       [pageSizeOptions]="[5, 10, 20]"> 
    </mat-paginator> 
</div> 

改ページコンポーネント:

import {Component, ViewChild} from '@angular/core'; 
import {MatPaginator, MatTableDataSource} from '@angular/material'; 

/** 
* @title Table with pagination 
*/ 
@Component({ 
    selector: 'table-pagination-example', 
    styleUrls: ['table-pagination-example.css'], 
    templateUrl: 'table-pagination-example.html', 
}) 
export class TablePaginationExample { 
    displayedColumns = ['position', 'name', 'weight', 'symbol']; 
    dataSource = new MatTableDataSource<Element>(ELEMENT_DATA); 

    @ViewChild(MatPaginator) paginator: MatPaginator; 

    /** 
    * Set the paginator after the view init since this component will 
    * be able to query its view for the initialized paginator. 
    */ 
    ngAfterViewInit() { 
    this.dataSource.paginator = this.paginator; 
    } 
} 

export interface Element { 
    name: string; 
    position: number; 
    weight: number; 
    symbol: string; 
} 

const ELEMENT_DATA: Element[] = [ 
    {position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H'}, 
    {position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'}, 
    {position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li'}, 
    {position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be'}, 
    {position: 5, name: 'Boron', weight: 10.811, symbol: 'B'}, 
    {position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C'}, 
    {position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N'}, 
    {position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O'}, 
    {position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F'}, 
    {position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne'}, 
    {position: 11, name: 'Sodium', weight: 22.9897, symbol: 'Na'}, 
    {position: 12, name: 'Magnesium', weight: 24.305, symbol: 'Mg'}, 
    {position: 13, name: 'Aluminum', weight: 26.9815, symbol: 'Al'}, 
    {position: 14, name: 'Silicon', weight: 28.0855, symbol: 'Si'}, 
    {position: 15, name: 'Phosphorus', weight: 30.9738, symbol: 'P'}, 
    {position: 16, name: 'Sulfur', weight: 32.065, symbol: 'S'}, 
    {position: 17, name: 'Chlorine', weight: 35.453, symbol: 'Cl'}, 
    {position: 18, name: 'Argon', weight: 39.948, symbol: 'Ar'}, 
    {position: 19, name: 'Potassium', weight: 39.0983, symbol: 'K'}, 
    {position: 20, name: 'Calcium', weight: 40.078, symbol: 'Ca'}, 
]; 

どのように私はの次のページをクリックするか、ページサイズ変更の変更イベントでトリガーするサーバー側の改ページを、達成することができます次のレコードを取得する。

https://stackblitz.com/angular/qxxpqbqolyb?file=app%2Ftable-pagination-example.ts

誰でもしてください?

答えて

1

この問題は、角度材料の文書のTable retrieving data through HTTPに続いてわかりました。すべてがにngAfterViewInitのおかげインサイドハンドルであることを

import {Component, AfterViewInit, ViewChild} from '@angular/core'; 
import {HttpClient} from '@angular/common/http'; 
import {MatPaginator, MatSort, MatTableDataSource} from '@angular/material'; 
import {Observable} from 'rxjs/Observable'; 
import {merge} from 'rxjs/observable/merge'; 
import {of as observableOf} from 'rxjs/observable/of'; 
import {catchError} from 'rxjs/operators/catchError'; 
import {map} from 'rxjs/operators/map'; 
import {startWith} from 'rxjs/operators/startWith'; 
import {switchMap} from 'rxjs/operators/switchMap'; 

/** 
* @title Table retrieving data through HTTP 
*/ 
@Component({ 
    selector: 'table-http-example', 
    styleUrls: ['table-http-example.css'], 
    templateUrl: 'table-http-example.html', 
}) 
export class TableHttpExample implements AfterViewInit { 
    displayedColumns = ['created', 'state', 'number', 'title']; 
    exampleDatabase: ExampleHttpDao | null; 
    dataSource = new MatTableDataSource(); 

    resultsLength = 0; 
    isLoadingResults = false; 
    isRateLimitReached = false; 

    @ViewChild(MatPaginator) paginator: MatPaginator; 
    @ViewChild(MatSort) sort: MatSort; 

    constructor(private http: HttpClient) {} 

    ngAfterViewInit() { 
    this.exampleDatabase = new ExampleHttpDao(this.http); 

    // If the user changes the sort order, reset back to the first page. 
    this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0); 

    merge(this.sort.sortChange, this.paginator.page) 
     .pipe(
     startWith({}), 
     switchMap(() => { 
      this.isLoadingResults = true; 
      return this.exampleDatabase!.getRepoIssues(
      this.sort.active, this.sort.direction, this.paginator.pageIndex); 
     }), 
     map(data => { 
      // Flip flag to show that loading has finished. 
      this.isLoadingResults = false; 
      this.isRateLimitReached = false; 
      this.resultsLength = data.total_count; 

      return data.items; 
     }), 
     catchError(() => { 
      this.isLoadingResults = false; 
      // Catch if the GitHub API has reached its rate limit. Return empty data. 
      this.isRateLimitReached = true; 
      return observableOf([]); 
     }) 
    ).subscribe(data => this.dataSource.data = data); 
    } 
} 

export interface GithubApi { 
    items: GithubIssue[]; 
    total_count: number; 
} 

export interface GithubIssue { 
    created_at: string; 
    number: string; 
    state: string; 
    title: string; 
} 

/** An example database that the data source uses to retrieve data for the table. */ 
export class ExampleHttpDao { 
    constructor(private http: HttpClient) {} 

    getRepoIssues(sort: string, order: string, page: number): Observable<GithubApi> { 
    const href = 'https://api.github.com/search/issues'; 
    const requestUrl = 
     `${href}?q=repo:angular/material2&sort=${sort}&order=${order}&page=${page + 1}`; 

    return this.http.get<GithubApi>(requestUrl); 
    } 
} 

ルック:たとえば、あなたが必要なテーブルの上にすべてのもの、改ページ、ソートや他のもの、コードを処理するためにngAfterViewInit()プラス観測を使用していると言うこと

観察可能な行this.resultsLength = data.total_count;はあなたのサービスが総登録数でデータを返すことを期待しています。私の場合、私はspringbootを使用しています。

さらに詳しい説明が必要な場合は、コメントを記入して回答を更新しますが、ドキュメントからその例を確認するとわかります。

+0

私はサーバーサイドページネーションでもpaginatorを使用しようとしていますが、次のページと前のページイベントをどのように管理しますか? thnx – bre

+0

@breイベントをコントロールにサブスクライブすると、イベントが発生してデータが更新されたときに検出されます。 –

+0

こんにちは、ありがとうございました。しかし、私はngxdatatableを使って終了しました:-) – bre

2

Wilfredoの答え(https://stackoverflow.com/a/47994113/986160)に基づいて、いくつかの部分が質問にも欠けていたので、完全な実例をまとめました。ここではより一般的なサーバー側のページ付けのためのケースと角度5とマテリアルデザインを使用してソートです(まだフィルタリングをプラグインする必要があります) - うまくいけば、それが誰かに参考になります。

ページングコンポーネント:

import { ViewChild, Component, Inject, OnInit, AfterViewInit } from '@angular/core'; 
import { EntityJson } from './entity.json'; 
import { EntityService } from './entity.service'; 
import { MatPaginator, MatSort, MatTableDataSource } from '@angular/material'; 
import { Observable } from 'rxjs/Observable'; 
import { merge } from 'rxjs/observable/merge'; 
import { of as observableOf } from 'rxjs/observable/of'; 
import { catchError } from 'rxjs/operators/catchError'; 
import { map } from 'rxjs/operators/map'; 
import { startWith } from 'rxjs/operators/startWith'; 
import { switchMap } from 'rxjs/operators/switchMap'; 

@Component({ 
    selector: 'entity-latest-page', 
    providers: [EntityService], 
    styles: [` 
     :host mat-table { 
      display: flex; 
      flex-direction: column; 
      min-width: 100px; 
      max-width: 800px; 
      margin: 0 auto; 
     } 
    `], 
    template: 
    `<mat-card> 
     <mat-card-title>Entity List 
     <button mat-button [routerLink]="['/create/entity']"> 
      CREATE 
     </button> 
     </mat-card-title> 
     <mat-card-content> 
      <mat-table #table matSort [dataSource]="entitiesDataSource" matSort class="mat-elevation-z2"> 
       <ng-container matColumnDef="id"> 
        <mat-header-cell *matHeaderCellDef mat-sort-header> Id </mat-header-cell> 
        <mat-cell *matCellDef="let element"> {{element.id}} </mat-cell> 
       </ng-container> 
       <ng-container matColumnDef="name"> 
        <mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell> 
        <mat-cell *matCellDef="let element"> {{element.name}} </mat-cell> 
       </ng-container> 
       <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> 
       <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row> 
      </mat-table> 
     </mat-card-content> 
     <mat-card-content> 
      <mat-paginator #paginator [length]="resultsLength" 
       [pageSize]="5" 
       [pageSizeOptions]="[5, 10, 20]"> 
      </mat-paginator> 
     </mat-card-content> 
    </mat-card> 
    ` 
}) 
export class EntityLatestPageComponent implements AfterViewInit { 

    private entities: EntityJson[]; 
    private entitiesDataSource: MatTableDataSource<EntityJson> = new MatTableDataSource(); 
    private displayedColumns = ['id', 'name']; 

    resultsLength = 0; 
    isLoadingResults = false; 
    isRateLimitReached = false; 

    @ViewChild(MatPaginator) paginator: MatPaginator; 
    @ViewChild(MatSort) sort: MatSort; 

    public constructor(@Inject(EntityService) private entityService: EntityService) { 
    } 

    public ngAfterViewInit() { 

     // If the user changes the sort order, reset back to the first page. 
     this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0); 
     merge(this.sort.sortChange, this.paginator.page) 
     .pipe(
      startWith({}), 
      switchMap(() => { 
      this.isLoadingResults = true; 
      return this.entityService.fetchLatest(this.sort.active, this.sort.direction, 
        this.paginator.pageIndex + 1, this.paginator.pageSize, 
        (total) => this.resultsLength = total); 
      }), 
      map(data => { 
      this.isLoadingResults = false; 
      this.isRateLimitReached = false; 
      //alternatively to response headers; 
      //this.resultsLength = data.total; 
      return data; 
      }), 
      catchError(() => { 
      this.isLoadingResults = false; 
      this.isRateLimitReached = true; 
      return observableOf([]); 
      }) 
     ).subscribe(data => this.entitiesDataSource.data = data); 
    } 
} 

サービス:

import { EntityJson } from './entity.json'; 
import { ApiHelper } from '../common/api.helper'; 
import { Http, Headers, Response, RequestOptions } from '@angular/http'; 
import { Inject, Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 
import { AuthenticationService } from '../auth/authentication.service'; 
import { stringify } from 'query-string'; 

@Injectable() 
export class EntityService { 

    private options: RequestOptions; 
    private apiPrefix: string; 
    private apiEndpoint: string; 

    constructor(
     @Inject(Http) private http: Http, 
     @Inject(AuthenticationService) private authService: AuthenticationService) { 

     this.options = authService.prepareRequestHeaders(); 
     this.apiPrefix = 'http://localhost:4200/api/v1/'; 
     this.apiEndpoint = this.apiPrefix + 'entities'; 
    } 

    public fetchLatest(sort: string = '', order: string = '', page: number = 1, perPage: number = 5, initTotal: Function =() => {}): Observable<EntityJson[]> { 
     return this.http.get(this.apiEndpoint +'?' + EntityService.createUrlQuery({sort: {field: sort, order: order}, pagination: { page, perPage }}), this.options) 
      .map((res) => { 
       const total = res.headers.get('x-total-count').split('/').pop(); 
       initTotal(total); 
       return JSON.parse(res.text()).content 
      }); 
    } 

    //should be put in a util 
    static createUrlQuery(params: any) { 
     if (!params) { 
      return ""; 
     } 

     let page; 
     let perPage; 
     let field; 
     let order; 
     let query: any = {}; 
     if (params.pagination) { 
      page = params.pagination.page; 
      perPage = params.pagination.perPage; 
      query.range = JSON.stringify([ 
       page, 
       perPage, 
      ]); 
     } 
     if (params.sort) { 
      field = params.sort.field; 
      order = params.sort.order; 
      if (field && order) { 
       query.sort = JSON.stringify([field, order]); 
      } 
      else { 
       query.sort = JSON.stringify(['id', 'ASC']); 
      } 
     } 
     if (!params.filter) { 
      params.filter = {}; 
     } 
     if (Array.isArray(params.ids)) { 
      params.filter.id = params.ids; 
     } 

     if (params.filter) { 
      query.filter = JSON.stringify(params.filter) 
     } 
     console.log(query, stringify(query)); 
     return stringify(query); 
    } 
} 

春ブーツ休憩コントローラのエンドポイント

@GetMapping("entities") 
public Iterable<Entity> filterBy(
     @RequestParam(required = false, name = "filter") String filterStr, 
     @RequestParam(required = false, name = "range") String rangeStr, @RequestParam(required = false, name="sort") String sortStr) { 
    //my own helpers - for source: https://github.com/zifnab87/react-admin-java-rest 
    //FilterWrapper wrapper = filterService.extractFilterWrapper(filterStr, rangeStr, sortStr); 
    //return filterService.filterBy(wrapper, repo); 
} 

いくつかの注意:

  1. 必ずモジュールをインポートしてください:MatTableModuleMatPaginatorModuleMatSortModule材料設計から他のモジュールに沿って。
  2. 私は、Springブート@ControllerAdviceを通して入力するレスポンスヘッダx-total-countからresultsLength(合計)を入力することに決めました。代わりにEntityServiceから返されたオブジェクトからこの情報を得ることができます(例えば、Springブートの場合はPage)。anyを戻り値の型として使用する必要があることを意味します。タイプセーフ "です。
関連する問題