【问题标题】:Mat Paginator of Mat Tabledoesn't work with api dataMat Table 的 Mat Paginator 不适用于 api 数据
【发布时间】:2020-09-23 23:33:44
【问题描述】:

我见过类似的问题,但似乎没有什么对我有用。我有一个垫子表,我在其中显示来自 api 的数据。但我不知道如何遍历“数据源”。下面是我的代码,以及我在检查控制台日志时如何获取数据。 ts文件

import {AfterViewInit, Component, OnInit, ViewChild} from '@angular/core';
import {Pokemon, PokemonData} from '../../models/pokemon';
import {PokemonService} from '../../models/services/pokemon.service';
import {ActivatedRoute} from '@angular/router';
import {MatTableDataSource} from '@angular/material/table';
import {MatPaginator} from '@angular/material/paginator';

@Component({
  selector: 'app-pokemon',
  templateUrl: './pokemon.component.html',
  styleUrls: ['./pokemon.component.css']
})
export class PokemonComponent implements OnInit {
  public pokemon: Pokemon[];
  public name: string;
  public url: string;
  public type: string;
  expandedElement: PokemonData | null;
  dataSource = new MatTableDataSource();
  displayPokemonColumns: string[] = ['name', 'url', 'pokemonDetails'];
  @ViewChild(MatPaginator, {read: true}) paginator: MatPaginator;
  //
  // // tslint:disable-next-line:typedef
  // tslint:disable-next-line:typedef
  // ngAfterViewInit() {
  //   // this.dataSource.paginator = this.paginator;
  // //
  // }

  constructor(private pokemonService: PokemonService, private route: ActivatedRoute) {
  }

  // function (which is called below)issues call to API. subscribes shows to the results that are returned. adds results to shows array
  onLoadPokemonList(): void {
  this.pokemonService.getPokemonList().subscribe(
    res => {
  // this.pokemon = JSON.parse(JSON.stringify(res));
  this.pokemon = res;
  this.dataSource.data = this.pokemon;
  setTimeout(() => {
        this.dataSource.paginator = this.paginator;

      });
  console.log(this.dataSource);
    });

  }


  ngOnInit(): void {
  this.onLoadPokemonList();

  }


}

html文件

<div class="table"  *ngIf="pokemon">
  <h1 matColumnDef="title">POKEDEX</h1>
  <table mat-table #table [dataSource]="dataSource" class="mat-elevation-z8" multiTemplateDataRows>
<!--    <table mat-table [dataSource]="pokemon.results" class="mat-elevation-z8" multiTemplateDataRows>-->
    <ng-container matColumnDef="name">
      <th mat-header-cell *matHeaderCellDef> Name </th>
<!--  <td mat-cell *matCellDef="let res"> {{res?.name}} </td>-->
      <td mat-cell *matCellDef="let res"> {{res.name}} </td>
    </ng-container>
    <ng-container matColumnDef="url">
      <th mat-header-cell *matHeaderCellDef> URL </th>
      <td mat-cell *matCellDef="let res"> {{res.url}} </td>
    </ng-container>
    <ng-container matColumnDef="pokemonDetails">
      <th mat-header-cell *matHeaderCellDef> Pokemon Details </th>
      <td mat-cell *matCellDef="let res">
        <button mat-raised-button color="primary" routerLink="/pokemonData/{{res.name}}">Pokemon Details</button>
      </td>
    </ng-container>
    <tr mat-header-row *matHeaderRowDef="displayPokemonColumns; sticky: true"></tr>
    <tr mat-row *matRowDef="let row; columns: displayPokemonColumns;"
        class="example-element-row"
        [class.example-expanded-row]="expandedElement === row"
        (click)="expandedElement = expandedElement === row ? null : row"></tr>
    </table>
  <mat-paginator #paginator
                 [pageSize]="10"
                 [pageSizeOptions]="[5, 10, 20]">
  </mat-paginator>
</div>

这是我返回的数据:

MatTableDataSource {_renderData: BehaviorSubject, _filter: BehaviorSubject, _internalPageChanges: Subject, _renderChangesSubscription: Subscriber, sortingDataAccessor: ƒ, …}filterPredicate: (data, filter) => {…}filteredData: {count: 1050, next: "https://pokeapi.co/api/v2/pokemon?offset=150&limit=150", previous: null, results: Array(150)}sortData: (data, sort) => {…}sortingDataAccessor: (data, sortHeaderId) => {…}_data: BehaviorSubject {_isScalar: false, observers: Array(1), closed: false, isStopped: false, hasError: false, …}_filter: BehaviorSubject {_isScalar: false, observers: Array(1), closed: false, isStopped: false, hasError: false, …}_internalPageChanges: Subject {_isScalar: false, observers: Array(0), closed: false, isStopped: false, hasError: false, …}_paginator: undefined_renderChangesSubscription: Subscriber {closed: false, _parentOrParents: null, _subscriptions: Array(1), syncErrorValue: null, syncErrorThrown: false, …}_renderData: BehaviorSubject {_isScalar: false, observers: Array(1), closed: false, isStopped: false, hasError: false, …}data: (...)filter: (...)paginator: (...)sort: (...)__proto__: DataSource

我需要的数据在filteredData下面。

当我这样做时

<table mat-table [dataSource]="pokemon.results" class="mat-elevation-z8" multiTemplateDataRows>

我得到了正确的表,而不是 dataSource,但分页器(显然)不起作用。

【问题讨论】:

    标签: angular api mat-pagination


    【解决方案1】:

    问题在于,当您尝试分配分页器时,分页器不在 DOM 中(您在具有 *ngIf 的 div 下有 mat-paginator)。您需要对 Angular 进行“更改”才能获得它,因此您需要将其包含在订阅函数中的 setTimeout 中

    this.pokemonService.getPokemonList().subscribe(res => {
      //why you use JSON.stringify? in Angular by defect a http.get return a json
      this.pokemon = JSON.parse(JSON.stringify(res));
      // this.pokemon = res;
      this.dataSource.data = this.pokemon;
    
       //here you indicate the paginator
       setTimeout(()=>{
        this.dataSource.paginator = this.paginator;
       })
    });
    

    简要说明:在您订阅并获取数据之前,您的变量“pokemon”为空或未定义。 (请记住,您在 html 中有 *ngIf="pokemon")。当您获取数据时,变量具有值,因此,“当 Angular 完成指令时”,刷新应用程序以显示表格。这就是原因,因为你需要一个 setTimeout

    【讨论】:

    • 我按照你的建议做了,但数据源仍然没有指向我需要的东西。如果我使用 dataSource 作为 dataSource 没有结果(我已经相应地更新了代码)。响应还是一样
    【解决方案2】:

    最终起作用的是删除模板上的 *ngIf 条件。我在堆栈溢出时找到了这个解决方案。 Paginator 现在可以正常工作了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-19
      • 1970-01-01
      • 1970-01-01
      • 2020-03-09
      • 2019-09-25
      • 1970-01-01
      • 1970-01-01
      • 2020-02-23
      相关资源
      最近更新 更多