【问题标题】:Cannot add pagination to my angular project无法向我的角度项目添加分页
【发布时间】:2021-06-18 14:41:30
【问题描述】:

我已经尝试了所有我知道的东西,但没有成功。我想为 covid-19 表添加分页。分页器显示表中有多少行,但它不会将它们分成页面。

这是我完成的代码。

这是我的component.ts

import { AfterViewInit, Component, HostListener, OnInit, ViewChild, } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTable } from '@angular/material/table';
import { merge } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Countries, sortData } from '../app.model';
import { AppService } from '../app.service';
import { DataTableDataSource } from './data-table-datasource';
import { animate, state, style, transition, trigger, } from '@angular/animations';

@Component({
    selector: 'app-data-table',
    templateUrl: './data-table.component.html',
    styleUrls: ['./data-table.component.css'],
    animations: [
        trigger('detailExpand', [
            state('collapsed', style({ height: '0px', minHeight: '0' })),
            state('expanded', style({ height: '*' })),
            transition(
                'expanded <=> collapsed',
                animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')
            ),
        ]),
    ],
})
export class DataTableComponent implements AfterViewInit {
    @ViewChild(MatPaginator, { static: true }) paginator!: MatPaginator;
    @ViewChild(MatSort) sort!: MatSort;
    @ViewChild(MatTable) table!: MatTable<Countries>;
    @ViewChild('paginator', { read: MatPaginator }) paginatorlist: MatPaginator;
    dataSource: DataTableDataSource;
    filter: sortData = new sortData();

    /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
    displayedColumns = [];
    scrWidth: any;
    constructor(public appService: AppService) { }

    ngOnInit() {
        this.dataSource = new DataTableDataSource(this.appService);
        this.sortData(false);
        this.setupTable();
        this.getScreenSize();
    }

    sortData(isChange: boolean) {
        if (isChange) {
            this.filter.pageSize = this.paginator.pageSize;
            this.filter.pageNumber = this.paginator.pageIndex + 1;
            // this.filter.sortColumn = this.sort.active;
            // this.filter.sortDirection = this.sort.direction;
            console.log(this.paginator.pageIndex);
        } else {
            this.filter.pageSize = 15;
            this.filter.pageNumber = 1;
            // this.filter.sortColumn = 'todayCases';
            // this.filter.sortDirection = 'true';
            // console.log(this.filter);
        }
        this.dataSource.loadData(this.filter);
        (error) => console.error(error);
    }

    ngAfterViewInit() {
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort;
    }
}

这是我的datasource.ts

import { DataSource } from '@angular/cdk/collections';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { finalize, map } from 'rxjs/operators';
import { Observable, of as observableOf, merge, BehaviorSubject } from 'rxjs';
import { ApiResponse, Countries, sortData } from '../app.model';
import { AppService } from '../app.service';

export class DataTableDataSource extends DataSource<Countries> {
    
    public dataSubject = new BehaviorSubject<Countries[]>([]);
    private loadingSubject = new BehaviorSubject<boolean>(false);
    public loading$ = this.loadingSubject.asObservable();
    private totalDataCountSubject = new BehaviorSubject<number>(0);
    public totalDataCount$ = this.totalDataCountSubject.asObservable();
    paginator: MatPaginator;
    sort: MatSort;

    constructor(private appService: AppService) {
        super();
    }

    loadData(filter: sortData) {
        this.appService
            .getData(filter)
            .pipe(finalize(() => this.loadingSubject.next(false)))
            .subscribe((data: any) => {
                // console.log(data.response);
                if (data) {
                    this.totalDataCountSubject.next(data.length);
                    this.dataSubject.next(data);
                    console.log(data.length);
                }
            });
    }

    connect(): Observable<Countries[]> {
        return this.dataSubject.asObservable();
    }

    disconnect(): void {
        this.dataSubject.complete();
        this.totalDataCountSubject.complete();
        this.loadingSubject.complete();
    }
}

这是我的HTML

<div class="mat-elevation-z8 data-table">
    <table mat-table multiTemplateDataRows class="full-width-table" matSort matSortActive="todayCases" matSortDirection="asc"
        aria-label="Elements" [dataSource]="dataSource">
        <!-- Country Column -->
        <ng-container matColumnDef="country">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Country</th>
            <td mat-cell *matCellDef="let row">{{ row.country }}</td>
        </ng-container>

        <!-- Name Column -->
        <ng-container matColumnDef="cases">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Cases</th>
            <td mat-cell *matCellDef="let row">{{ row.cases }}</td>
        </ng-container>
        <!-- Id Column -->
        <ng-container matColumnDef="active">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Active</th>
            <td mat-cell *matCellDef="let row">{{ row.active }}</td>
        </ng-container>
        <!-- Id Column -->
        <ng-container matColumnDef="todayCases">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Today Cases</th>
            <td mat-cell *matCellDef="let row">{{ row.todayCases }}</td>
        </ng-container>
        <!-- Id Column -->
        <ng-container matColumnDef="todayDeaths">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Total Deaths</th>
            <td mat-cell *matCellDef="let row">{{ row.todayDeaths }}</td>
        </ng-container>

        <!-- Id Column -->
        <ng-container class="recovered" matColumnDef="recovered">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Recovered</th>
            <td mat-cell *matCellDef="let row">{{ row.recovered }}</td>
        </ng-container>
        <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
        <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
    </table>

    <mat-paginator #paginator [length]="dataSource.totalDataCount$ | async" [pageSize]="15" [pageSizeOptions]="[15, 20, 25]">
    </mat-paginator>
</div>

提前致谢

【问题讨论】:

  • 我已经检查了你的StackBlitz。在DataUrl 中,您没有为pageSizepageNumber 传递任何查询字符串参数。这是为什么呢?

标签: angular pagination mat-table


【解决方案1】:

问题是您必须将可用数据总长度设置为paginatorpageSize 参数。

例如,您有 30 个国家/地区的数据,而您的 pageSize10。因此,您必须将paginatorpageSize 参数设置为30,您的可见数据将为10

我用静态数据模拟了你的AppService。并展示了如何为分页填充数据。

您还错过了更改pageSizepage 后的过滤数据。我也这样做了。

观看演示,您将能够理解。

Stackblitz创建的工作解决方案

【讨论】:

  • 我明白了逻辑,但对于固定数据:),我还是个菜鸟。这是我的StackBlitz
  • 查看答案中最新的 StackBlitz 链接。
  • 它没有加载任何数据
  • 你解决了我的问题!太感谢了!你是救世主!
【解决方案2】:

您的 Api 端似乎不支持数据分页。即使您在查询字符串中使用pageSizepageNumber 参数请求,它也会返回所有数据。

解决方案是在客户端对数据进行分页。您当前使用的数据源类型 (DataSource&lt;T&gt;) 将在客户端数据分页场景中增加更多复杂性。您应该使用 MatTableDataSource&lt;T&gt; 作为数据源 - 一旦您提供所有数据,它就会支持自动数据分页。

以下是您的StackBlitz 的修改/简化版本,您可以尝试 -

组件代码-

export class GalleryComponent implements OnInit {

    @ViewChild(MatPaginator, { static: true }) paginator!: MatPaginator;
    @ViewChild(MatSort) sort!: MatSort;
    dataSource = new MatTableDataSource<Countries[]>([]);
    displayedColumns = ['country', 'cases', 'active', 'todayDeaths', 'recovered'];
    filter: sortData = new sortData();

    constructor(public appService: AppService) { }

    ngOnInit() {
        this.loadData();
    }

    loadData() {
        this.filter.sortColumn = 'country';
        this.filter.sortDirection = 'asc';
        this.appService.getData(this.filter).subscribe(
            p => {
                this.dataSource.data = p;
            },
            e => {
                console.log(e);
            });
    }

    ngAfterViewInit() {
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort;
    }
}

在模板代码中,仅从 mat-paginator 中删除 length 绑定 -

<mat-paginator [pageSize]="15" [pageSizeOptions]="[15, 20, 25]"> </mat-paginator>

这应该足以使您的分页工作。你不需要使用DataTableDataSource

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 2017-11-15
    • 1970-01-01
    • 2021-04-15
    • 2018-12-04
    相关资源
    最近更新 更多