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