angular - 材料表分页器在一个巨大的页面上显示所有数据而不是分页
问题描述
根据此处找到的示例,我正在使用带有分页器的材料表(查看名为 的示例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
}
解决方案
问题是,起初您的表是隐藏的,因此,当您制作时,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?
推荐阅读
- javascript - How to find most common number in array using link in JavaScript?
- api - 多个带有 axios 的 api 客户端和 react native
- php - 如何编写 Laravel GroupBy 查询?
- python - error with module multiprocessing under python3.8
- html - I used overlapping on image but the second image didn't show on the RWD(just the first pic have it)
- java - Android JNI 错误:NoSuchMethodError:没有非静态方法
- jenkins - 尝试更新一些旧 Jenkins 作业的配置时出现 ERR_CONNECTION_RESET 错误
- spring-boot - Spring Boot soap client auto retry
- ionic-framework - how to use *ngIf in in displaying input that has id
- php - mysqli_fetch_assoc not working with mysqli_stmt_store_result