typescript - Angular Material tablosunda sunucudan gelen veri kaynağına MatPaginator nasıl eklenir?


Angular 5 projemde ızgara oluşturmak için Angular Material tablosu kullanıyorum. Verilerim HTTP isteğinden geliyor ve view.ts dosyasında dataSourceNew adında bir değişkene atanıyor. Burada dataSourceNew dinamik içeriğe ve yapıya sahip, bu yüzden herhangi bir arayüz ihracatı yapmıyorum.

      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

         });

Bu sözdizimini kullanarak html dosyasında başarıyla bir veri tablosu oluşturabiliyorum.

     <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>

Şimdi bu tabloya bir sayfalama eklemek istiyorum ve bunun için bunu tanımladım

 @ViewChild(MatPaginator) paginator: MatPaginator;

Ama HTML'de tabloya sayfalama eklediğimde şöyle,

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

Konsolda aşağıdaki hatayı aldım ve bu uygulamamı bozuyor.

Bunu zaten içe aktardım

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

İlgili .ts dosyasında.

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.

Ayrıca bunu logladığımda this.dataSourcenew: Bu nesnenin paginator öğesi boş : Angular Material paginator'ü herhangi bir arayüz oluşturmadan nasıl kullanabilirim?

Güncelleme :

David'in önerisiyle: Ana uygulama modülünün importlarına MatPaginator ekledim. Şimdi sayfalama bloğu mükemmel bir şekilde görünüyor.

Ama Mevcut Kayıtlar "0 of 0" olarak görünüyor. Aslında 14 kaydım olmasına rağmen ve Kayıt sayısını değiştirme, ileri, geri gibi Sayfalama işlevleri çalışmıyor. Neyim eksik?

Güncelleme 2: Paginator etiketlerine Length özelliğini uyguladım. Şimdi sayfalama düzgün çalışıyor. Sorun şu ki, artık datatable mevcut satır sayısını değiştirmiyor.

Güncelleme 3: Pierre Mallet'in önerisine göre gerekli değişiklikleri yaptım. Artık [length]i açıkça belirtmeden toplam kayıt API yanıtından çıkarılıyor. Ayrıca, sayfalayıcı this.matdatasource=new MatTableDataSource([]); ile doğru şekilde bağlandı. Bu nedenle bunu başarmak için şimdiye kadar herhangi bir açık kodlama yapılmadı.

Şimdi sadece başlangıçta birkaç kayıt almak istiyorum (diyelim ki 20) ve sonra sonraki taleplerden veritabanı çağrısı yapmak istiyorum, böylece tüm kayıtlar için veritabanına tek seferde başvurmam gerekmiyor. Bunu nasıl gerçekleştirebilirim?

Cevap #1

Paginator'ınızı MatTableDataSource ile "bağlamadan" önce oluşturulmasını beklemeniz gerekir, bu yüzden genellikle paginator'a @ViewChild(MatPaginator) paginator: MatPaginator; ile ulaşmak için AfterViewInit kancalarını dinlersiniz.

Ama verileriniz de asenkron olduğundan, yapmalısınız

  1. boş bir VeriKaynağı başlat
  2. Verileriniz hazır olduğunda dataSource'u doldurun
  3. görünüm render edildikten sonra sayfalayıcıyı bağla

Bunu deneyebilir misin?

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

Cevap #2

Öncelikle, sayfalayıcıyı başlatın

@ViewChild(MatPaginator) paginator: MatPaginator;

Sonra dataSource'u doldurun

this.matdatasource = new MatTableDataSource([])

Ve nihayet

this.dataSource.paginator = this.paginator;

Bunu doğru anladığınızdan emin olun

İlgili makaleler