首页 > 解决方案 > 材料表分页器在一个巨大的页面上显示所有数据而不是分页

问题描述

根据此处找到的示例,我正在使用带有分页器的材料表(查看名为 的示例Data table with sorting, pagination, and filtering)。但是,它实际上并没有将我的数据分成页面。分页器填充了我设置的正确数字,但它仍然在一页上显示所有数据。

奇怪的是,我让它工作了,所以我提交了我的代码,然后再次检查,没有任何变化,它停止工作。

模板:

<h1>Pokémon List</h1>
<div class="loading" *ngIf="isLoading">Loading...</div>
<div class="error" *ngIf="isError">Error loading Pokémon.</div>
<div class="container" *ngIf="!isLoading && !isError">

    <form class="parameter-form">
        <mat-form-field appearance="fill">
            <mat-label>Generation</mat-label>
            <mat-select [(value)]="selectedGenNumber" (selectionChange)="loadPokemon()">
                <mat-option *ngFor="let gen of generations" [value]="gen.id">
                    {{gen.name}}
                </mat-option>
            </mat-select>
        </mat-form-field>

        <mat-form-field appearance="fill">
            <mat-label>Site</mat-label>
            <mat-select [(value)]="selectedSite">
                <mat-option *ngFor="let site of availableSites;" [value]="site.name">
                    {{site.name}}
                </mat-option>
            </mat-select>
        </mat-form-field>
    </form>

    <form class="search-form">
        <mat-form-field class="search-field">
            <mat-label>Name or Number</mat-label>
            <input name="search" (keyup)="applyFilter($event)" placeholder="Name or Number" #input matInput
                type="search" autofocus />
        </mat-form-field>
    </form>

    <table mat-table [dataSource]="pokemonDataSource" class="mat-elevation-z8">
        <tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
        <tr mat-row *matRowDef="let row; columns: columnsToDisplay"></tr>
        <ng-container matColumnDef="image">
            <th mat-header-cell *matHeaderCellDef></th>
            <td mat-cell *matCellDef="let pokemon"><img width="50" height="50"
                    [src]="'https://img.pokemondb.net/artwork/'+pokemon.name+'.jpg'" /></td>
        </ng-container>
        <ng-container matColumnDef="number">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Number </th>
            <td mat-cell *matCellDef="let pokemon"> {{pokemon.number}} </td>
        </ng-container>
        <ng-container matColumnDef="name">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
            <td mat-cell *matCellDef="let pokemon"> {{pokemon.displayName}} </td>
        </ng-container>
        <ng-container matColumnDef="evolution-link">
            <th mat-header-cell *matHeaderCellDef> Evolution </th>
            <td mat-cell *matCellDef="let pokemon"> <a mat-raised-button color="primary" target="_blank"
                    [href]="pokemon.evolutionUrls[selectedSite]">Evolution</a></td>
        </ng-container>
        <ng-container matColumnDef="location-link">
            <th mat-header-cell *matHeaderCellDef> Location </th>
            <td mat-cell *matCellDef="let pokemon"> <a mat-raised-button [href]="pokemon.locationUrls[selectedSite]"
                    target="_blank" color="accent">Location</a>
            </td>
        </ng-container>
        <ng-container matColumnDef="effectiveness-link">
            <th mat-header-cell *matHeaderCellDef> Effectiveness </th>
            <td mat-cell *matCellDef="let pokemon"> <a mat-raised-button
                    [href]="pokemon.effectivenessUrls[selectedSite]" target="_blank" color="warn">Effectiveness</a>
            </td>
        </ng-container>
        <ng-container matColumnDef="learnset-link">
            <th mat-header-cell *matHeaderCellDef> Moveset </th>
            <td mat-cell *matCellDef="let pokemon"> <a mat-raised-button [href]="pokemon.learnsetUrls[selectedSite]"
                    target="_blank" color="primary">Learnset</a>
            </td>
        </ng-container>
    </table>
    <mat-paginator [length]="selectedGeneration.pokemonCount" [pageSize]="10" [pageSizeOptions]="[10,20, 50, 100]"
        showFirstLastButtons>
    </mat-paginator>
</div>

打字稿:

import { Component, OnInit, ViewChild } from '@angular/core';
import { Pokemon } from 'src/Pokemon';
import { PokeApiService } from 'src/app/poke-api.service';
import { TextFormat } from 'src/app/TextFormat';
import { Sites } from 'src/app/Sites';
import { Site } from 'src/app/Site';
import { TemplateKeywords } from 'src/app/TemplateKeywords';
import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { Generation } from '../Generation';

@Component({
    selector: 'app-pokemon-list',
    templateUrl: './pokemon-list.component.html',
    styleUrls: ['./pokemon-list.component.css']
})
export class PokemonListComponent implements OnInit {
    pokemon: Pokemon[] = [];
    columnsToDisplay: string[] = ["image", "number", "name", "evolution-link", "location-link", "effectiveness-link", "learnset-link"];
    searchText: string = '';
    isLoading: boolean;
    isError: boolean = false;

    availableSites: Site[]; //DATA WILL GO HERE
    currentGen: number = 8;
    generationNumbers: number[] = Array(this.currentGen);
    generations: Generation[] =
        [new Generation(1, 151),
        new Generation(2, 251),
        new Generation(3, 386),
        new Generation(4, 493),
        new Generation(5, 649),
        new Generation(6, 721),
        new Generation(7, 807),
        new Generation(8, 893)];

    pokemonDataSource: MatTableDataSource<Pokemon> = new MatTableDataSource();
    @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
    @ViewChild(MatSort, { static: true }) sort: MatSort;

    selectedSite: string = "SITE HERE"; //TODO: change this to be a parameter
    selectedGenNumber: number = 8;
    selectedGeneration: Generation;

    constructor(private pokeApiService: PokeApiService) {
    }

    ngOnInit() {
        this.loadPokemon();
    }

    loadPokemon() {
        console.log("hello");
        this.selectedGeneration = this.getGenerationForNumber(this.selectedGenNumber);
        if (this.selectedGeneration) {
            this.isLoading = true;
            this.pokeApiService.getAllPokemon(this.selectedGeneration.pokemonCount).then((response) => {
                let data = response;
                console.log("this right here", data);
                const pokemon = data.map(p => {
                    return {
                        name: p.name,
                        displayName: TextFormat.ToTitleCase(p.name),
                        number: p.number,
                        evolutionUrls: this.buildEvolutionUrls(p.name, p.number),
                        locationUrls: this.buildLocationUrls(p.name, p.number),
                        effectivenessUrls: this.buildEffectivenessUrls(p.name, p.number),
                        learnsetUrls: this.buildLearnsetUrls(p.name, p.number)
                    } as Pokemon;
                });
                this.pokemonDataSource = new MatTableDataSource(pokemon);
                this.pokemonDataSource.paginator = this.paginator;
                this.pokemonDataSource.sort = this.sort;
                this.isLoading = false;
            });
        }
        else {
            this.isError = true;
        }
    }

    applyFilter(event: Event) {
        const filterValue = (event.target as HTMLInputElement).value;
        this.pokemonDataSource.filter = filterValue.trim().toLowerCase();

        if (this.pokemonDataSource.paginator) {
            this.pokemonDataSource.paginator.firstPage();
        }
    }

    getGenerationForNumber(genNumber: number) {
        console.log("gen", genNumber);
        return this.generations.find(g => g.id == genNumber);
    }
//trimmed off some functions referenced above to keep this simpler, they're just utility functions
}

标签: angularangular-material

解决方案


问题是,起初您的表是隐藏的,因此,当您制作时,this.pokemonDataSource.paginator = this.paginator;您还没有数据源。我认为你可以解决给 Angular 一个呼吸,那就是:使用 setTimeout

this.pokeApiService.getAllPokemon(this.selectedGeneration.pokemonCount).then(
    ....
    //first "isLoading=false"
    this.isLoading = false;
    //create the dataSource and paginator enclosed in a setTimeout
    setTimeout(()=>{
         this.pokemonDataSource = new MatTableDataSource(pokemon);
         this.pokemonDataSource.paginator = this.paginator;
         this.pokemonDataSource.sort = this.sort;
    })
)

顺便说一句,有什么理由使用 Promise 而不是 Observables?


推荐阅读