【问题标题】:mat-table sorting in Angular 8 is working differently, uppercase, lowercase are sorting differently along with numbers and null valuesAngular 8 中的 mat-table 排序工作方式不同,大写、小写以及数字和空值的排序方式不同
【发布时间】:2021-01-12 17:42:32
【问题描述】:

我已经使用 mat 表实现了通用数据表。除排序外,所有事情都运行良好。 当数据包含大写和小写单词时,排序会对小写、大写、数字和空值进行单独排序。我尝试了所有东西,我认为缺少一些我无法弄清楚的东西。 请检查下面的代码。感谢您的帮助。

包依赖

 "dependencies": {
    "@angular/animations": "8.2.12",
    "@angular/cdk": "~8.2.3",
    "@angular/common": "8.2.12",
    "@angular/compiler": "8.2.12",
    "@angular/core": "8.2.12",
    "@angular/forms": "8.2.12",
    "@angular/material": "^8.2.3",
    "@angular/platform-browser": "8.2.12",
    "@angular/platform-browser-dynamic": "8.2.12",
    "@angular/platform-server": "8.2.12",
    "@angular/router": "8.2.12",
    "@azure/msal-angular": "^1.0.0",
    "@ng-select/ng-select": "^3.7.3",
    "@nguniversal/module-map-ngfactory-loader": "8.1.1",
    "aspnet-prerendering": "^3.0.1",
    "bootstrap": "^4.3.1",
    "core-js": "^3.3.3",
    "hammerjs": "^2.0.8",
    "jquery": "3.4.1",
    "msal": "^1.3.2",
    "ngx-spinner": "^9.0.2",
    "ngx-toastr": "^12.0.0",
    "oidc-client": "^1.9.1",
    "popper.js": "^1.16.0",
    "rxjs": "^6.5.3",
    "rxjs-compat": "^6.5.4",
    "zone.js": "0.9.1"
  }

data-table.component.html

<mat-form-field>
  <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>
<mat-table #table [dataSource]="dataSource" matSort class="mat-elevation-z8">
  <ng-container *ngFor="let column of Columns" matColumnDef="{{column.ColumnName}}">
    <mat-header-cell *matHeaderCellDef mat-sort-header [ngStyle]="{'background-color': 'lightgray','text-align':'left!important'}" ><b><u>{{column.DisplayText}}</u></b></mat-header-cell>
    <mat-cell *matCellDef="let DataSet" style="word-wrap: break-word!important;display: table-cell;padding-left:0px!important;padding-right:0px!important;text-align:left!important;" >
      <ng-container *ngIf="column.ColumnName == 'Edit' || column.ColumnName == 'Delete'; then EditDelete; else Normal">
      </ng-container>
      <ng-template #Normal>
        <span class="mobile-label">{{column.DisplayText}}:</span>
        <ng-container *ngIf="column.Pipe || column.Pipe != ''; then SelectPipe; else NoPipe">
        </ng-container>
        <ng-template #SelectPipe>
          <div style="word-wrap: break-word!important;text-align:left!important">{{DataSet[column.ColumnName]+'' | dynamicPipe: column.Pipe : column.PipeArgs}}</div>
        </ng-template>
        <ng-template #NoPipe> <div style="word-wrap: break-word!important;text-align:left!important">{{DataSet[column.ColumnName]}}</div></ng-template>
      </ng-template>
      <ng-template #EditDelete>
        <span class="mobile-label" *ngIf="column.ColumnName == 'Edit'">{{column.DisplayText}}:</span>
        <ng-container *ngIf="column.DisplayText=='View'; then ViewDisplay; else EditDisplay">
        </ng-container>
        <ng-template #ViewDisplay>
          <div style="cursor:pointer!important;" *ngIf="column.ColumnName == 'Edit'"><i class="fas fa-binoculars  text-success"  (click)="onEdit(DataSet[IdColumnName])"></i></div>
        </ng-template>
        <ng-template #EditDisplay>
          <div style="cursor:pointer!important;" *ngIf="column.ColumnName == 'Edit'"><i class="fas fa-edit text-success" (click)="onEdit(DataSet[IdColumnName])"></i></div>
        </ng-template>
        <span class="mobile-label" *ngIf="column.ColumnName == 'Delete'">{{column.DisplayText}}:</span>
        <ng-container *ngIf="column.DisplayText=='Void'; then VoidDisplay; else DeleteDisplay">
        </ng-container>
        <ng-template #VoidDisplay>
          <div style="cursor:pointer!important;" *ngIf="column.ColumnName == 'Delete'"><i class="fas fa-minus-circle  text-danger" (click)="onDelete(DataSet[IdColumnName], DataSet[MessageColumn])"></i></div>
        </ng-template>
        <ng-template #DeleteDisplay>
          <div style="cursor:pointer!important;" *ngIf="column.ColumnName == 'Delete'"><i class="far fa-trash-alt fa-lg text-danger" (click)="onDelete(DataSet[IdColumnName], DataSet[MessageColumn])"></i></div>
        </ng-template>
      </ng-template>
    </mat-cell>
  </ng-container>
  <mat-header-row *matHeaderRowDef="ColumnNames;sticky: true"></mat-header-row>
  <mat-row *matRowDef="let row; columns: ColumnNames;"></mat-row>
</mat-table>
<mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>

data-table.component.ts

import { Component, OnInit, ViewChild, AfterViewInit, EventEmitter, Output, Input, OnChanges } from '@angular/core';
import { MatPaginator, MatTableDataSource, MatSort } from '@angular/material';

@Component({
  selector: 'app-data-table',
  templateUrl: './data-table.component.html',
  styleUrls: ['./data-table.component.css']
})
export class DataTableComponent implements OnInit, AfterViewInit, OnChanges {

  constructor() {
    if (this.DataSet) { this.dataSource = new MatTableDataSource<any>(this.DataSet); }
  }

  ngOnInit() {
    if (this.DataSet) {
      this.dataSource.data = this.DataSet;
      this.dataSource.paginator = this.paginator;
      this.dataSource.sort = this.sort;
    }
  }

  ngAfterViewInit(): void {
    if (this.DataSet) {
      this.dataSource.paginator = this.paginator;
      this.dataSource.sort = this.sort;
    }
  }

  ngOnChanges() {
    if (this.DataSet) {
      this.ColumnNames = this.Columns.map(c => c.ColumnName);
      this.dataSource = new MatTableDataSource<any>(this.DataSet);
      this.dataSource.paginator = this.paginator;
      this.dataSource.sort = this.sort;
    }
  }

  @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator;
  @ViewChild(MatSort, { static: true }) sort: MatSort;
  dataSource: MatTableDataSource<any>;

  //Input parameters from parent components
  @Input() public MessageColumn;
  @Input() public IdColumnName;
  @Input() public DataSet: any[];
  @Input() public Columns: DisplayColumns[];
  @Input() ColumnNames: string[];
  @Input() public DisplayAddButton: boolean = false;

  //Raising events 
  @Output() public EditEvent = new EventEmitter();
  @Output() public DeleteEvent = new EventEmitter();
  @Output() public AddEvent = new EventEmitter();

  //Send Add event to the caller
  onAdd() {
    this.AddEvent.emit();
  }
  //Send edit event with Id to the caller
  onEdit(Id) {
    this.EditEvent.emit(Id);
  }
  //Send delete event with Id and Message value(this value is useful when caller to show which item name got deleted) to the caller
  data: any[];
  onDelete(Id, MessageValue) {
    this.data = [{ 'Id': Id, 'MessageValue': MessageValue }];
    this.DeleteEvent.emit(this.data);
  }

  //search in the table all column values
  applyFilter(filterValue: string) {
    this.dataSource.filter = filterValue.trim().toLowerCase();
    if (this.dataSource.paginator) {
      this.dataSource.paginator.firstPage();
    }
  }
}

export class DisplayColumns {
  ColumnName: string;
  DisplayText: string;
}

export class DisplayColumnsWithFormat {
  ColumnName: string;
  DisplayText: string;
  Pipe: object;
  PipeArgs:string[];
}

在不同组件中调用数据表

sample.component.html

  <app-data-table [Columns]="columns" [DataSet]="dataSet"></app-data-table>

sample.component.ts

const ELEMENT_DATA: PeriodicElement[] = [
  { position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H' },
  { position: 2, name: 'helium', weight: 4.0026, symbol: 'He' },
  { position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li' },
  { position: 4, name: 'beryllium', weight: 9.0122, symbol: 'Be' },
  { position: 5, name: 'Boron', weight: 10.811, symbol: 'B' },
  { position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C' },
  { position: 7, name: 'nitrogen', weight: 14.0067, symbol: 'N' },
  { position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O' },
  { position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F' },
  { position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne' },
];

  columns: DisplayColumns[] = [
    { 'ColumnName': 'position', 'DisplayText': 'Position' },
    { 'ColumnName': 'name', 'DisplayText': 'Name' },
    { 'ColumnName': 'weight', 'DisplayText': 'Weight' },
    { 'ColumnName': 'symbol', 'DisplayText': 'Symbol' },
    { 'ColumnName': 'Edit', 'DisplayText': 'Edit' },
    { 'ColumnName': 'Delete', 'DisplayText': 'Delete' }
  ];

  dataSet = ELEMENT_DATA;

结果 sorting lower case and upper case

【问题讨论】:

  • 请尽量缩小您的示例代码,如果可以,请给我们一个可重复的示例来帮助您。如果你能在 stackblitz 上做一些简单的事情,请去做。
  • Juan,我尝试使用 stackblitz,但由于版本更改而出现很多错误,修复这些错误是另一项艰巨的任务。该代码是 mat table 的通用版本,您可以从任何组件调用代码。我会贴出不同组件中调用的代码
  • 胡安,你检查代码了吗?

标签: angular sorting mat-table


【解决方案1】:

您可以覆盖方法sortingDataAccessor。在此处查看详细信息:https://github.com/angular/components/issues/9205

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多