Angular 5 Выбор мата материала: фильтр на основе выбранного значения, - PullRequest
0 голосов
/ 28 июня 2018

Итак, у меня есть приложение Angular 5, использующее таблицу данных углового материала, и на нем у меня есть фильтрация, сортировка, разбиение на страницы и т. Д. Сейчас я могу фильтровать по значению, которое пользователь вводит в поле ввода, это работает. Теперь я хочу иметь то же самое на основе выбора входа. Таким образом, есть 2 входа, которые пользователь может использовать: 1 поле ввода, где пользователь может вводить текст, 1 поле выбора, где пользователь может выбрать один из вариантов. Я хочу, чтобы моя таблица также фильтровала, основываясь на том, какую опцию выбрал пользователь, но сейчас она не работает.

Вот мой 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');
  }

}

Прямо сейчас, что именно происходит при загрузке страницы, он будет делать событие "onSelectionChange" для каждого элемента, который загружается в "EADDPStages [0]" !! Таким образом, он загрузится, перейдет к первому элементу, затем войдет в метод applySelectFilter, затем обнаружит, что у него есть второй параметр, снова перейдет к методу applySelectFilter, третьему элементу и т. Д. Он будет делать это до полной загрузки страницы, тогда, казалось бы, фильтр не применяется. Когда я выбираю опцию в mat-select, она снова перебирает все значения, в то время как все, что мне нужно, это применить фильтр на основе значения, которое я выбрал!

Кто-нибудь видит потенциальную проблему?

1 Ответ

0 голосов
/ 28 июня 2018

Я считаю, что (onSelectionChange) устарело с версии Angular 5. Я рекомендую использовать (selectionChange) в соответствии с Angular Material 5 Docs . С помощью этого метода вы можете определить, когда пользователь делает выбор, и применить фильтр к выбранному элементу.

В вашей разметке:

<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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...