web-dev-qa-db-ja.com

angularマテリアルテーブルのサーバーからのデータソースにMatPaginatorをアタッチする方法は?

私は angular Material table を使用してmy Angular 5プロジェクトにグリッドを作成します。私のデータはhttpリクエストからのもので、そのデータはdataSourceNewという名前の変数に割り当てられています。 .tsファイル。ここでは、dataSourceNewに動的なコンテンツと構造があるため、インターフェイスをエクスポートしていません。

_      this.http.get('http://example.org?,{headers: this.headers})
          .subscribe(
          res => { 

           this.displayedColumnsNew = res.record;
           this.dataSourceNew = res.data;
           this.matdatasource = new MatTableDataSource(this.dataSourceNew);
           this.dataSourceNew.paginator = this.paginator;
           console.log("got matdatasource object",this.matdatasource);
      // attached the result of this log below

         });
_

この構文を使用してHTMLファイルでデータテーブルを正常に作成できます。

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


       <ng-container  *ngFor="let head of tableData.record; let i= index; " matColumnDef="{{head}}" (click)="setClickedRow(ddata) "  [class.active]="ddata[primaryid] == selectedRow">
               <mat-header-cell *matHeaderCellDef> {{tableData.gridhead[i]}} 
                </mat-header-cell>
              <mat-cell *matCellDef="let element"> {{element[head]}} </mat-cell>
         </ng-container>


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

今、私はこのページにページネーションを付けたいので、これを宣言しました

_ @ViewChild(MatPaginator) paginator: MatPaginator;
_

しかし、このようにhtmlでテーブルにページネーションを付けると、

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

コンソールで以下のエラーが発生し、アプリケーションが壊れます。

私はすでにこれをインポートしました

_import {MatPaginator, MatTableDataSource} from '@angular/material';
_

それぞれの.tsファイル。

_Uncaught Error: Template parse errors:
Can't bind to 'pageSize' since it isn't a known property of 'mat-paginator'.
1. If 'mat-paginator' is an Angular component and it has 'pageSize' input, then verify that it is part of this module.
2. If 'mat-paginator' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.
_

また、this.dataSourcenewをログに記録すると、このオブジェクトのpaginator要素が空になります。インターフェイスを作成せずにangularマテリアルpaginatorを使用するにはどうすればよいですか?

更新:

Davidの提案に従い、メインのアプリモジュールのインポートにMatPaginatorを追加しました。これで、ページ分割ブロックが完全に表示されました。

しかし、現在のレコードは「0/0」と表示されます。 14レコードありますが、レコード数の変更、次へ、前へなどのページネーション機能が機能していません。何が欠けていますか?

更新2:プロパティLengthをページ編集タグに適用しました。現在、ページ編集は正常に機能しています。問題は、データテーブルが現在の番号を変更していないことです。行の。

更新3:Pierre Malletからの提案に従って、必要な変更を行いました。そして今、[長さ]の合計レコードを明示的に伝えることなく、API応答から推論されています。また、ページネータはmy this.matdatasource = new MatTableDataSource([]);に正しくバインドされているため、これを実現するために、これまで明示的なコーディングは行われていません。

ここで、最初にいくつかのレコード(20とします)をフェッチし、その後、後続のリクエストからデータベースコールを実行したいので、すべてのレコードに対して一度にデータベースにアクセスする必要はありません。これを達成する方法は?

パジネーターがインスタンス化されるのを待ってから、MatTableDataSourceに「リンク」する必要があるため、通常、AfterViewInitフックをリッスンして、パジネーターを@ViewChild(MatPaginator) paginator: MatPaginator;から取得します。

しかし、データも非同期なので、

  1. 空のデータソースを初期化する
  2. データの準備ができたらdataSourceにデータを入力します
  3. ビューがレンダリングされた後にページネーションをリンクする

これやってみませんか?

export class YourComponent implements AfterViewInit {

  private this.matdatasource;

  // get refereence to paginator
  @ViewChild(MatPaginator) paginator: MatPaginator;

  constructor (private http: HttpClient) {
    // 1/ init
    this.matdatasource = new MatTableDataSource([]);
    this.http.get('http://example.org?,{headers: this.headers})
      .subscribe(res => { 
        // 2/ populate with data
        this.matdatasource.data = res.data;
      });
  }

  // 3/ link paginator when empty dataSource is created
  // and paginator rendered
  ngAfterViewInit() {
    this.dataSource.paginator = this.paginator;
  }

}
6
Pierre Mallet

まず、ページネーションをインスタンス化します

@ViewChild(MatPaginator) paginator: MatPaginator;

次に、dataSourceを入力します

this.matdatasource = new MatTableDataSource([])

そして最後に

this.dataSource.paginator = this.paginator;

this をチェックして適切に理解してください

3
Akitha_MJ

@ mateo-tibaquiraのアイデアの簡単なバージョンを以下に示します。ハイライトは次のとおりです。

  • DataSourceObservableを組み合わせて、一時的な読み込み状態と、サービス呼び出しから発生するエラーをキャプチャします。
  • バックエンドサービスコールから返された総数に基づいて、ページネーターlengthを更新します。
  • タイプTの応答配列をラップするために使用されるPage<T>汎用クラス。ページネーションヘッダー情報pageSizepageIndexおよびtotalCountを追加します。
  • バックエンドコールが<mat-table>および<mat-paginator>と互換性のあるページネーションパラメータをサポートしていると想定します。

このコードは、優れたAngular Materialブログエントリ Angular Material Data Table:A Complete Example(Server Pagination、Filtering、Sorting )

custom-data-source.ts

import { map, catchError, finalize,
         debounceTime, distinctUntilChanged, startWith, tap, delay 
       } from "rxjs/operators";

import { CollectionViewer, DataSource } from "@angular/cdk/collections";
import { MatPaginator }                 from '@angular/material';

import { Page } from '../model/page';

export class CustomDataSource<T> implements DataSource<T>, Observer<Page<T>> 
{
    private items = new BehaviorSubject<Page<T>>( new Page<T>() );
    private loading = new BehaviorSubject<boolean>(false);
    private err = new BehaviorSubject<any>( {} );

    protected paginator: MatPaginator;

    items$ = this.items.asObservable();
    loading$ = this.loading.asObservable();
    error$ = this.err.asObservable();

    closed = false;

    constructor( protected itemType: string ) {
    }

    next( results: Page<T> ) : void {
        console.debug( "Found items: ", this.itemType, results );
        if ( this.paginator ) {
            this.paginator.length = results.totalCount;
        }
        this.items.next( results );
    }
    error( errr: any ) : void {
        console.error( "Error loading items: ", this.itemType, errr );
        this.err.next( errr );
    }
    complete() : void {
        console.debug( "Done loading items.", this.itemType );
        this.loading.next( false );
    }

    connect( collectionViewer: CollectionViewer ) : Observable<Page<T>> {
        this.closed = false;
        return this.items$;
    }

    disconnect( collectionViewer: CollectionViewer ): void {
        this.closed = true;
        this.items.complete();
        this.loading.complete();
        this.err.complete();
    }

    protected preLoad() : void {
        this.err.next( {} );
        this.loading.next( true );
    }

    setPaginator( pgntr: MatPaginator ) : void {
        this.paginator = pgntr;
    }
}

model/page.ts

export class Page<T> extends Array<T> {
    public static readonly DEFAULT_PAGE_SIZE: number = 10;

    pageIndex: number;
    pageSize: number;
    totalCount: number;

    constructor( pgIx?: number, pgSize?: number, tot?: number, items?: T[] )
    {
        super();
        this.pageIndex = pgIx ? pgIx : 0;
        this.pageSize = pgSize ? pgSize : 0;
        this.totalCount = tot ? tot : 0;
        if ( items && items.length > 0 ) {
            this.Push( ...items );
        }
    }
}

xyz-data-source.ts

import { Xyz } from '../model/xyz';
import { CustomDataSource } from './custom-data-source';
import { XyzService } from '../service/xyz-service';

export class XyzDataSource extends CustomDataSource<Xyz>
{
    constructor( private xyzService: XyzService ) {
        super( 'Xyz' );
    }

    loadXyz( offset: number = 0, limit: number = 10, predicates?: any ) : void
    {
        this.preLoad();

        this.xyzService
            .searchXyz( offset, limit, predicates )
            .subscribe( this );
    }    
}
1
Charlie Reitzel

@matheo/datasourceデータベースとデータソースのクリーンセットアップを構築し、問題なくすべてを適切に配置します。

すべての種類のページネーション応答(およびFirebaseのようなページネーションデータもなし)を使用してさまざまなAPIをマウントし、これらのすべてのケースの合計数を問題なく処理しました。

詳細については、以下を参照してください。
https://medium.com/@matheo/reactive-datasource-for-angular-1d869b0155f6

ライブラリが好きなら、私はあなたのユースケースであなたを助けることができます
ハッピーコーディング!

1
Mateo Tibaquira