简体   繁体   English

Angular Material 8 中的排序表

[英]Sort table in Angular Material 8

I am new to angular and started building after going through the videos and referring to the docs.我是 angular 的新手,在浏览视频并参考文档后开始构建。 Pagination works perfectly fine but I have problem sorting the table.分页工作得很好,但我在对表格进行排序时遇到问题。 I have tried the following.我尝试了以下方法。

component.html组件.html

    <table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">

        <!-- Name Column -->
        <ng-container matColumnDef="Name">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
            <td mat-cell *matCellDef="let environment"> <a for="env" id="env"
                (click)="openEditDialog(environment)">{{environment.environmentName}}</a> </td>
        </ng-container>

        <!-- URL Column -->
        <ng-container matColumnDef="URL">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> URL </th>
            <td mat-cell *matCellDef="let environment"> {{environment.url}} </td>
        </ng-container>

        <!-- Username Column -->
        <ng-container matColumnDef="Username">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Username </th>
            <td mat-cell *matCellDef="let environment"> {{environment.userName}} </td>
        </ng-container>

        <!-- Details Column -->
        <ng-container matColumnDef="Details">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Details </th>
            <td mat-cell *matCellDef="let environment"> {{environment.details}} </td>
        </ng-container>

        <!-- Delete Column -->
        <ng-container matColumnDef="Delete">
            <th mat-header-cell *matHeaderCellDef> Delete </th>
            <td mat-cell *matCellDef="let environment"><a for="deleteEnvironment" id="deleteEnvironment"
                (click)="deleteEnvironment(environment._id)">
                <mat-icon style="color: #d2002b;">delete_forever</mat-icon>
            </a> </td>
        </ng-container>

        <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
        <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
    </table>
    <mat-paginator style="bottom: 0px; position: sticky;" [length]="100" [pageSize]="10" [pageSizeOptions]="[5, 10, 25, 100]" showFirstLastButtons>
        </mat-paginator>

Here's my component.ts file这是我的 component.ts 文件

            import { Component, OnInit, Inject, ViewChild } from '@angular/core';
            import { FormGroup, FormBuilder } from '@angular/forms';
            import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
            import {EnvironmentService} from '../../services/environment.service';
            import {Environment} from '../../services/environment.model';
            import {MatSort} from '@angular/material/sort';
            import {MatTableDataSource} from '@angular/material/table';
            import { MatPaginator } from '@angular/material';

            export interface DialogData {  
              environment: string;    
              dialogTitle: string;
            }

            @Component({
              selector: 'app-environment',
              templateUrl: './environment.component.html',
              styleUrls: ['./environment.component.css'],
              providers: [EnvironmentService] 
            })
            export class EnvironmentComponent implements OnInit {
              environmentDetailsForm: FormGroup;
              serverErrorMessages : string;
              environments: Environment[] = []; 
              displayedColumns = ['Name', 'URL', 'Username', 'Details', 'Delete'];

              // dataSource: MatTableDataSource<Environment>;
              dataSource = new MatTableDataSource(this.environments);

              @ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
              @ViewChild(MatSort, {static: true}) sort: MatSort;

              constructor(private formBuilder: FormBuilder,
                private environmentService:EnvironmentService,
                private router: Router,
                private dialog: MatDialog) { }

              ngOnInit() {
                this.environmentDetailsForm = this.formBuilder.group({});
                this.loadAllEnvironments();
                this.dataSource.sort = this.sort;
              }
            private loadAllEnvironments() {
                this.environmentService.getEnvironmentDetails()
                .subscribe(environments => {
                  this.environments = environments; 
                  this.dataSource = new MatTableDataSource(this.environments);
                  this.dataSource.paginator = this.paginator;
                });
                return this.environments;
            }
}

app.module.ts file app.module.ts 文件

import { MatTableModule, MatPaginatorModule, MatSortModule } from from '@angular/material';

imports: [
    MatTableModule,
    MatPaginatorModule,
    MatSortModule
]

I am getting Up and down arrows on clicking the table headers and there is no error in the console .单击表标题时出现向上和向下箭头,并且控制台中没有错误 But the sorting functionality didn't work.但是排序功能不起作用。 If something is missing, please let me know.如果有什么遗漏,请告诉我。

It looks like the only thing you're missing is to link the matSortChange event to a function in your typescript for sorting.看起来您唯一缺少的是将 matSortChange 事件链接到打字稿中的函数以进行排序。 Try something like this:尝试这样的事情:

In your HTML:在您的 HTML 中:

<mat-table matSort (matSortChange)="sortData($event)" />

In your TypeScript:在你的打字稿中:

// import Sort:
import {Sort} from '@angular/material/sort';

// define function to handle sorting:
sortData(sort: Sort) {
    const data = this.environments.slice();
    if (!sort.active || sort.direction === '') {
        this.dataSource = data;
        return;
    }

    this.dataSource = data.sort((a, b) => {
        const isAsc = sort.direction === 'asc';
        switch (sort.active) {
            case 'name': return compare(a.name, b.name, isAsc);
            case 'username': return compare(a.username, b.username, isAsc);
            default: return 0;
        }
    });
}

function compare(a: number | string, b: number | string, isAsc: boolean) { 
    return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}

Finally, I knew what was missing.终于,我知道缺少了什么。 Had to specify mat-sort-header=" some name " so that I can compare using that name in the switch case mentioned by @tommytarheel.必须指定mat-sort-header=" some name "以便我可以在@tommytarheel 提到的开关案例中使用该名称进行比较。 We can do it this way.我们可以这样做。

<table mat-table [dataSource]="dataSource" matSort (matSortChange)="sortData($event)" class="mat-elevation-z8">
    <ng-container matColumnDef="Name">
          <th mat-header-cell *matHeaderCellDef mat-sort-header="name"> Name </th>
          <td mat-cell *matCellDef="let environment"> <a for="env" id="env"
            (click)="openEditDialog(environment)">{{environment.environmentName}}</a> </td>
    </ng-container>

Instead of代替

<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
    <ng-container matColumnDef="Name">
          <th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
          <td mat-cell *matCellDef="let environment"> <a for="env" id="env"
            (click)="openEditDialog(environment)">{{environment.environmentName}}</a> </td>
    </ng-container>

And in .ts file, as @tommytarheel mentioned, I have to make sortData function exactly same as he defined in his answer.在 .ts 文件中,正如@tommytarheel 所提到的,我必须使 sortData 函数与他在回答中定义的完全相同。

// import Sort:
import {Sort} from '@angular/material/sort';

// define function to handle sorting:
sortData(sort: Sort) {
    const data = this.environments.slice();
    if (!sort.active || sort.direction === '') {
        this.dataSource = data;
        return;
    }

    this.dataSource = data.sort((a, b) => {
        const isAsc = sort.direction === 'asc';
        switch (sort.active) {
            case 'name': return compare(a.name, b.name, isAsc);
            case 'username': return compare(a.username, b.username, isAsc);
            default: return 0;
        }
    });
}

function compare(a: number | string, b: number | string, isAsc: boolean) { 
    return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM