Angular 5 Material mat select: 根据值 selected 过滤,
Angular 5 Material mat select: filter based on value selected,
所以我有一个使用 Angular Material 数据 Table 的 Angular 5 应用程序,在上面我有过滤、排序、分页等。现在我可以根据值 a 进行过滤用户在输入字段中输入,这有效。现在我想要基于 select 输入的相同内容。因此,用户可以使用 2 个输入:1 个输入字段,用户可以在其中键入文本,1 个 select 字段,用户可以在其中 select 选择一个选项。我希望我的 table 也能根据用户 select 编辑的选项进行过滤,但现在它不起作用。
这是我的 HTML:
<div class="filterContainer" *ngIf="showDataForm">
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Search">
</mat-form-field>
</div>
<div class="filterSelectContainer" *ngIf="showDataForm">
<mat-select placeholder="Search EADDPStage">
<mat-option *ngFor="let stage of EADDPStages[0]" [value]="stage" (onSelectionChange)="applySelectFilter($event, stage)">
{{stage}}
</mat-option>
</mat-select>
</div>
<div class="container">
<mat-table #table class="dataTable" *ngIf="showDataForm;else loadingTemplate" [dataSource]="dataSource" matSort>
<ng-container matColumnDef="EOTAFileNr">
<mat-header-cell *matHeaderCellDef mat-sort-header>EOTAFileNr</mat-header-cell>
<mat-cell *matCellDef="let item">{{item.EOTAFileNr}}</mat-cell>
</ng-container>
<ng-container matColumnDef="ProcessRTAB">
<mat-header-cell *matHeaderCellDef mat-sort-header>ProcessRTAB</mat-header-cell>
<mat-cell *matCellDef="let item">{{item.ProcessRTAB}}</mat-cell>
</ng-container>
<ng-container matColumnDef="EADDPStage">
<mat-header-cell *matHeaderCellDef mat-sort-header>EADDPStage</mat-header-cell>
<mat-cell *matCellDef="let item">{{item.EADDPStage}}</mat-cell>
</ng-container>
<ng-container matColumnDef="RegistrationDate">
<mat-header-cell *matHeaderCellDef mat-sort-header>RegistrationDate</mat-header-cell>
<mat-cell *matCellDef="let item">{{item.RegistrationDate}}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="columnsToDisplay"></mat-header-row>
<mat-row *matRowDef="let item; columns: columnsToDisplay"></mat-row>
</mat-table>
<mat-paginator *ngIf="showDataForm" [pageSize]="10" [pageSizeOptions]="[5, 10, 25]" showFirstLastButtons></mat-paginator>
</div>
<ng-template #loadingTemplate>
<div>
<p>Please wait, the data is loading...</p>
<img src="../../assets/giphy.gif">
</div>
</ng-template>
<button mat-raised-button class="submitButton" color="accent" (click)="logout()">Logout and remove cookie</button>
这是我的 TS 文件:
import { Component, OnInit, ChangeDetectorRef, ViewChild, ElementRef } from '@angular/core';
import { Router } from '@angular/router';
import { CookieService } from 'ngx-cookie-service';
import { LoginService } from '../Services/login.service';
import { TableService } from '../Services/table.service';
import { EADProcess } from '../Classes/EADProcess';
import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { map, tap, catchError } from 'rxjs/operators';
@Component({
selector: 'app-table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {
sort;
paginator;
showDataForm = false;
stringArray: string[] = [];
eadItems: EADProcess[] = [];
EADDPStages: string[] = [];
dataSource: MatTableDataSource<EADProcess>;
// @ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatPaginator) set contentPaginator(contentPaginator: ElementRef) {
this.paginator = contentPaginator;
if (this.paginator) {
this.dataSource.paginator = this.paginator;
}
}
@ViewChild(MatSort) set contentSort(contentSort: ElementRef) {
this.sort = contentSort;
if (this.sort) {
this.dataSource.sort = this.sort;
}
}
// which columns the data table needs to display
columnsToDisplay: string[] = ['EOTAFileNr', 'ProcessRTAB', 'EADDPStage', 'RegistrationDate'];
constructor(private router: Router,
private cookieService: CookieService,
private loginService: LoginService,
private tableService: TableService,
private chRef: ChangeDetectorRef) {
}
ngOnInit() {
const $this = this;
this.getEADDPStages();
}
public getEADDPStages() {
const json: any = {(data omitted for example)};
const jsonStringified = JSON.stringify(json);
this.tableService.getEADDPStages(jsonStringified).subscribe(res => {
this.convertJsonEADDPStagesToArray(res);
this.getAllEadItems();
});
}
public getAllEadItems() {
const json: any = {(data omitted for example)};
const jsonStringified = JSON.stringify(json);
this.tableService.getAllEadItems(jsonStringified).subscribe(res => {
this.convertJsonResultToArray(res);
this.dataSource = new MatTableDataSource(this.eadItems);
this.dataSource.paginator = this.paginator;
this.showDataForm = true;
});
}
public applyFilter(filterValue: string) {
filterValue = filterValue.trim();
filterValue = filterValue.toLowerCase();
this.dataSource.filter = filterValue;
}
public applySelectFilter(event: Event, filterValue: string) {
filterValue = filterValue.trim();
filterValue = filterValue.toLowerCase();
this.dataSource.filter = filterValue;
}
public convertJsonResultToArray(res: any) {
this.stringArray = JSON.parse(res);
for (const eadItem of this.stringArray) {
const ead = new EADProcess();
ead.id = eadItem['GUID'];
ead.titel = eadItem['Title'];
ead.EADDraftingStage = eadItem['EADDraftingStage'];
ead.EOTAFileNr = eadItem['EOTAFileNr'];
ead.ProcessRTAB = eadItem['ProcessRTAB']['LookupValue'];
ead.EADDPStage = eadItem['EADDPStage'];
ead.RegistrationDate = this.formatDate(eadItem['RegistrationDate']);
this.eadItems.push(ead);
}
}
public formatDate(date) {
const d = new Date(date);
let month = '' + (d.getMonth() + 1);
let day = '' + d.getDate();
const year = d.getFullYear();
if (month.length < 2) {
month = '0' + month;
}
if (day.length < 2) {
day = '0' + day;
}
return [year, month, day].join('-');
}
public convertJsonEADDPStagesToArray(res: any) {
const arr = JSON.parse(res);
for (const item of arr['ReturnExtraValues']) {
this.EADDPStages.push(item);
}
const len = this.EADDPStages[0].length;
this.EADDPStages[0][len.toString()] = 'Closed';
}
public logout() {
this.cookieService.delete('logindata');
this.loginService.setLoggedIn(false);
this.router.navigateByUrl('/login');
}
}
现在确切发生在页面加载上,它将为加载到 "EADDPStages[0]" 中的每个项目执行 "onSelectionChange" 事件!!所以它会加载,去第一个项目,然后进入 applySelectFilter 方法,然后它看到它有第二个选项,将再次进入 applySelectFilter 方法,第三个项目等等......它会这样做直到页面完全加载,然后它似乎没有应用过滤器。当我 select 来自 mat-select 的选项时,它会再次遍历所有值,而我想要的只是让它根据我 selected 的值应用过滤器!
有人看到潜在的问题吗?
我认为 (onSelectionChange)
从 Angular 开始已被弃用 5. 我建议根据 Angular Material 5 Docs 使用 (selectionChange)
。使用该方法,您可以检测用户何时进行选择并对所选项目应用过滤器。
在您的标记中:
<div class="filterSelectContainer" *ngIf="showDataForm">
<mat-select placeholder="Search EADDPStage" (selectionChange)="selectStage($event)">
<mat-option *ngFor="let stage of EADDPStages[0]" [value]="stage">
{{stage}}
</mat-option>
</mat-select>
</div>
在您的代码隐藏中:
selectStage(event) {
applyFilter(event.value);
}
所以我有一个使用 Angular Material 数据 Table 的 Angular 5 应用程序,在上面我有过滤、排序、分页等。现在我可以根据值 a 进行过滤用户在输入字段中输入,这有效。现在我想要基于 select 输入的相同内容。因此,用户可以使用 2 个输入:1 个输入字段,用户可以在其中键入文本,1 个 select 字段,用户可以在其中 select 选择一个选项。我希望我的 table 也能根据用户 select 编辑的选项进行过滤,但现在它不起作用。
这是我的 HTML:
<div class="filterContainer" *ngIf="showDataForm">
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Search">
</mat-form-field>
</div>
<div class="filterSelectContainer" *ngIf="showDataForm">
<mat-select placeholder="Search EADDPStage">
<mat-option *ngFor="let stage of EADDPStages[0]" [value]="stage" (onSelectionChange)="applySelectFilter($event, stage)">
{{stage}}
</mat-option>
</mat-select>
</div>
<div class="container">
<mat-table #table class="dataTable" *ngIf="showDataForm;else loadingTemplate" [dataSource]="dataSource" matSort>
<ng-container matColumnDef="EOTAFileNr">
<mat-header-cell *matHeaderCellDef mat-sort-header>EOTAFileNr</mat-header-cell>
<mat-cell *matCellDef="let item">{{item.EOTAFileNr}}</mat-cell>
</ng-container>
<ng-container matColumnDef="ProcessRTAB">
<mat-header-cell *matHeaderCellDef mat-sort-header>ProcessRTAB</mat-header-cell>
<mat-cell *matCellDef="let item">{{item.ProcessRTAB}}</mat-cell>
</ng-container>
<ng-container matColumnDef="EADDPStage">
<mat-header-cell *matHeaderCellDef mat-sort-header>EADDPStage</mat-header-cell>
<mat-cell *matCellDef="let item">{{item.EADDPStage}}</mat-cell>
</ng-container>
<ng-container matColumnDef="RegistrationDate">
<mat-header-cell *matHeaderCellDef mat-sort-header>RegistrationDate</mat-header-cell>
<mat-cell *matCellDef="let item">{{item.RegistrationDate}}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="columnsToDisplay"></mat-header-row>
<mat-row *matRowDef="let item; columns: columnsToDisplay"></mat-row>
</mat-table>
<mat-paginator *ngIf="showDataForm" [pageSize]="10" [pageSizeOptions]="[5, 10, 25]" showFirstLastButtons></mat-paginator>
</div>
<ng-template #loadingTemplate>
<div>
<p>Please wait, the data is loading...</p>
<img src="../../assets/giphy.gif">
</div>
</ng-template>
<button mat-raised-button class="submitButton" color="accent" (click)="logout()">Logout and remove cookie</button>
这是我的 TS 文件:
import { Component, OnInit, ChangeDetectorRef, ViewChild, ElementRef } from '@angular/core';
import { Router } from '@angular/router';
import { CookieService } from 'ngx-cookie-service';
import { LoginService } from '../Services/login.service';
import { TableService } from '../Services/table.service';
import { EADProcess } from '../Classes/EADProcess';
import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { map, tap, catchError } from 'rxjs/operators';
@Component({
selector: 'app-table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {
sort;
paginator;
showDataForm = false;
stringArray: string[] = [];
eadItems: EADProcess[] = [];
EADDPStages: string[] = [];
dataSource: MatTableDataSource<EADProcess>;
// @ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatPaginator) set contentPaginator(contentPaginator: ElementRef) {
this.paginator = contentPaginator;
if (this.paginator) {
this.dataSource.paginator = this.paginator;
}
}
@ViewChild(MatSort) set contentSort(contentSort: ElementRef) {
this.sort = contentSort;
if (this.sort) {
this.dataSource.sort = this.sort;
}
}
// which columns the data table needs to display
columnsToDisplay: string[] = ['EOTAFileNr', 'ProcessRTAB', 'EADDPStage', 'RegistrationDate'];
constructor(private router: Router,
private cookieService: CookieService,
private loginService: LoginService,
private tableService: TableService,
private chRef: ChangeDetectorRef) {
}
ngOnInit() {
const $this = this;
this.getEADDPStages();
}
public getEADDPStages() {
const json: any = {(data omitted for example)};
const jsonStringified = JSON.stringify(json);
this.tableService.getEADDPStages(jsonStringified).subscribe(res => {
this.convertJsonEADDPStagesToArray(res);
this.getAllEadItems();
});
}
public getAllEadItems() {
const json: any = {(data omitted for example)};
const jsonStringified = JSON.stringify(json);
this.tableService.getAllEadItems(jsonStringified).subscribe(res => {
this.convertJsonResultToArray(res);
this.dataSource = new MatTableDataSource(this.eadItems);
this.dataSource.paginator = this.paginator;
this.showDataForm = true;
});
}
public applyFilter(filterValue: string) {
filterValue = filterValue.trim();
filterValue = filterValue.toLowerCase();
this.dataSource.filter = filterValue;
}
public applySelectFilter(event: Event, filterValue: string) {
filterValue = filterValue.trim();
filterValue = filterValue.toLowerCase();
this.dataSource.filter = filterValue;
}
public convertJsonResultToArray(res: any) {
this.stringArray = JSON.parse(res);
for (const eadItem of this.stringArray) {
const ead = new EADProcess();
ead.id = eadItem['GUID'];
ead.titel = eadItem['Title'];
ead.EADDraftingStage = eadItem['EADDraftingStage'];
ead.EOTAFileNr = eadItem['EOTAFileNr'];
ead.ProcessRTAB = eadItem['ProcessRTAB']['LookupValue'];
ead.EADDPStage = eadItem['EADDPStage'];
ead.RegistrationDate = this.formatDate(eadItem['RegistrationDate']);
this.eadItems.push(ead);
}
}
public formatDate(date) {
const d = new Date(date);
let month = '' + (d.getMonth() + 1);
let day = '' + d.getDate();
const year = d.getFullYear();
if (month.length < 2) {
month = '0' + month;
}
if (day.length < 2) {
day = '0' + day;
}
return [year, month, day].join('-');
}
public convertJsonEADDPStagesToArray(res: any) {
const arr = JSON.parse(res);
for (const item of arr['ReturnExtraValues']) {
this.EADDPStages.push(item);
}
const len = this.EADDPStages[0].length;
this.EADDPStages[0][len.toString()] = 'Closed';
}
public logout() {
this.cookieService.delete('logindata');
this.loginService.setLoggedIn(false);
this.router.navigateByUrl('/login');
}
}
现在确切发生在页面加载上,它将为加载到 "EADDPStages[0]" 中的每个项目执行 "onSelectionChange" 事件!!所以它会加载,去第一个项目,然后进入 applySelectFilter 方法,然后它看到它有第二个选项,将再次进入 applySelectFilter 方法,第三个项目等等......它会这样做直到页面完全加载,然后它似乎没有应用过滤器。当我 select 来自 mat-select 的选项时,它会再次遍历所有值,而我想要的只是让它根据我 selected 的值应用过滤器!
有人看到潜在的问题吗?
我认为 (onSelectionChange)
从 Angular 开始已被弃用 5. 我建议根据 Angular Material 5 Docs 使用 (selectionChange)
。使用该方法,您可以检测用户何时进行选择并对所选项目应用过滤器。
在您的标记中:
<div class="filterSelectContainer" *ngIf="showDataForm">
<mat-select placeholder="Search EADDPStage" (selectionChange)="selectStage($event)">
<mat-option *ngFor="let stage of EADDPStages[0]" [value]="stage">
{{stage}}
</mat-option>
</mat-select>
</div>
在您的代码隐藏中:
selectStage(event) {
applyFilter(event.value);
}