我正在使用Angular材质表,显示从后端获取的动态数据。单列搜索效果很好。现在,我想实现多列搜索。谁能帮我实现这个目标吗?
HTML
<div >
<ng-container *ngIf="columns && columns.length">
<table mat-table matTableExporter [dataSource]="dataSource" #exporter="matTableExporter">
<!-- actions -->
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>
Update
</th>
<td class="trendCol icons" mat-cell *matCellDef="let element;">
<button mat-icon-button style="margin:5px;" color="accent" (click)="navigateToTrendEdit(element.unique_id)">
<mat-icon aria-label="Edit">edit</mat-icon>
</button>
<button mat-icon-button style="margin:5px;" color="accent" (click)="deleteItem(element.unique_id)">
<mat-icon aria-label="Delete">delete</mat-icon>
</button>
</td>
</ng-container>
<ng-container *ngFor="let column of columns; let i = index" [matColumnDef]="column.columnDef">
<th mat-header-cell *matHeaderCellDef>
{{ column.header }}
<mat-icon class="filter_icon" (click)="openFilterDynamic(i)"
>filter_alt</mat-icon
><br>
<div *ngIf="openId === i">
<mat-form-field>
<input
matInput
type="text" [(ngModel)]="searchValue"
class="form-field"
(ngModelChange)="onSearchChange(column.columnDef)"
/>
<button mat-button *ngIf="searchValue" matSuffix mat-icon-button aria-label="Clear" (click)="closeSearch(column.columnDef)">
<mat-icon>close</mat-icon>
</button>
</mat-form-field>
</div>
</th>
<td class="trendCol" mat-cell *matCellDef="let row">
<div class="tooltip">
<span class="userRecord">{{ column.cell(row) }}</span>
<span class="tooltiptext">{{ column.cell(row) }}</span>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="dynamicColumns"></tr>
<tr mat-row *matRowDef="let row; columns: dynamicColumns"></tr>
</table>
<mat-paginator
[pageSize]="6"
[pageSizeOptions]="[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 20]"
showFirstLastButtons
>
</mat-paginator>
<div class="downloadDiv">
Download as :
<button style="margin:5px;" mat-raised-button (click)="exporter.exportTable('xlsx')">Excel</button>
<button style="margin:5px;" mat-raised-button (click)="exporter.exportTable('csv')">Csv</button>
<button style="margin:5px;" mat-raised-button (click)="exporter.exportTable('json')">Json</button>
<button style="margin:5px;" mat-raised-button (click)="exporter.exportTable('txt')">Txt</button>
</div>
</ng-container>
</div>
TS
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator } from '@angular/material/paginator';
import {MatDialog} from '@angular/material/dialog';
import { Router } from '@angular/router';
import {BehaviorSubject} from 'rxjs';
@Component({
selector: 'app-trends-list',
templateUrl: './trends-list.component.html',
styleUrls: ['./trends-list.component.scss'],
})
export class TrendsListComponent implements OnInit, AfterViewInit {
index: number;
id: string;
dataChange: BehaviorSubject<TrendsForView[]> = new BehaviorSubject<TrendsForView[]>([]);
public dataSource = new MatTableDataSource<TrendsForView>();
globalFilter = '';
@ViewChild(MatPaginator, {static: false})
set paginator(value: MatPaginator) {
this.dataSource.paginator = value;
}
columns: Array < {
columnDef: string;
header: string;
cell: (element: any) => any;
} > = [];
dynamicColumns = ['actions', ...this.columns.map(c => c.columnDef)];
searchValue = '';
openId: number;
constructor(private router: Router, private _router: Router,private trendsService: TrendsService, public dialog: MatDialog) {}
ngOnInit(): void {
this.getAllTrends();
this.dataSource.filterPredicate = this.customFilterPredicate();
}
onSearchChange(key: string) {
this.dataSource.filter = JSON.stringify({key, value: this.searchValue.toLowerCase()});
}
closeSearch(key: string) {
this.searchValue = '';
this.dataSource.filter = JSON.stringify({key, value: this.searchValue.toLowerCase()});
}
customFilterPredicate() {
const myFilterPredicate = (
data: TrendsForView,
filter: string
): boolean => {
let searchString = JSON.parse(filter);
if (this.searchValue) {
return data[searchString.key].toString().trim().toLowerCase().indexOf(searchString.value) !== -1;
} else {
return true;
}
}
return myFilterPredicate;
}
ngAfterViewInit(): void {
this.dataSource.paginator = this.paginator;
}
public getTrends = () =>{
this.trendsService.getTrend().subscribe((res) => {
this.dataSource.data = res.all_docs;
});
};
public getAllTrends = () => {
this.trendsService.getTrend().subscribe((res) => {
this.dataSource.data = res.all_docs;
const columns = this.dataSource.data[0];
if (columns) {
Object.keys(columns).forEach((key) => {
if(key!="unique_id"){
this.columns.push({
header: key.replace(/_/g, ' '),
columnDef: key,
cell: (element: any) => element[key]
});
}
});
this.dynamicColumns = ['actions', ...this.columns.map(c => c.columnDef)];
}
});
};
openFilterDynamic(index: number) {
this.openId = (this.openId === index) ? undefined : index;
this.closeSearch('')
}
public redirectToDetails = (id: string) => {
this.router.navigate(['/home']);
};
navigateToTrendEdit(id: any){
this._router.navigateByUrl('/home' + id);
}
deleteItem(id: any){
this.openDialog(id);
}
openDialog(id: any) {
const dialogRef = this.dialog.open(DeleteTrendDialogComponent,{
data: {
message: id
}
});
dialogRef.afterClosed()
.subscribe(result => {
if (result === 'closed') {
this.getTrends();
}
});
}
}
正如我所说的,单列搜索可以很好地工作,但是我对如何进行多列搜索感到困惑。
答案 0 :(得分:0)
您尝试过mat-table-filter软件包吗?
作为示例,您需要有一个示例实体来代表您的过滤对象,当您填充其属性时,表格会自动被过滤。
<table mat-table matTableFilter [dataSource]="dataSource" [exampleEntity]="exampleObject"...>