使用数组的内容过滤MatTableDataSource

时间:2019-08-06 10:42:44

标签: angular angular-material

我在Angular应用程序中有一个表,该表在其行中显示用户数据。我希望能够使用代表用户电子邮件的字符串数组来过滤此表。如果用户的电子邮件存在于数组中,那么我不希望该用户显示在表中。

我看过过滤Angular材质表specifically here的过程,其中它们使用单​​个字符串来过滤表。我似乎发现的所有示例还涉及使用单个字符串,例如,用户通过输入指定过滤字符串。

但是,我找不到使用字符串数组过滤数据的任何解决方案。我是否需要将整个数组连接成一个字符串,然后将其传递到filterPredicate属性中?

    applyAddedUserFilter() {
        this._usersService.addedUsers$.subscribe((addedUsers: AddedUser[]) => {
          let addedUserEmails: string[] = addedUsers.map(({ email }) => email);

          this.users.filterPredicate = (user: GoogleUser, filter: string) => { //<-- What exactly do I need to do here to use my string[] to filter my table's results?
            //Unsure what I need to do here.
          }
        });
      }

设置了过滤谓词后,还需要在哪里调用此方法。表格一旦建立就足以调用该方法了吗?

2 个答案:

答案 0 :(得分:0)

我会这样:

applyAddedUserFilter() {
    this._usersService.addedUsers$.subscribe((addedUsers: AddedUser[]) => {
      let addedUserEmails: string[] = addedUsers.map(user => user.email);

      this.dataSource.data = this.users.filter((user: GoogleUser) => !(addedUserEmails.indexOf(user.email) > -1));
    });
  }

这是一个堆叠闪电战:Material Table Filter

答案 1 :(得分:0)

这是一个较晚的答案,但肯定会对有兴趣的人有所帮助。

您可以使用mat-table-filter进行过滤。它也支持数组过滤。它使您无需实施包括反跳等在内的过滤样板。

您唯一需要做的就是向材料表中添加matTableFilter指令,并将exampleEntity绑定到数据源中作为项目的表示形式。

 <table mat-table matTableFilter [dataSource]="dataSource"
 [exampleEntity]="exampleObject"...>

仅此而已。当您填充exampleObject的属性时,在默认的防反跳支持下,过滤器将自动正常运行。您还可以更改反跳时间。

您可以在此处查看示例:https://halittalha.github.io/ng-material-extensions/

我在下面共享完整的数组过滤源代码。 下面的示例利用芯片组件收集数组内容进行过滤。

.html

<mat-table matTableFilter [exampleEntity]="filterEntity" [filterType]="filterType" [dataSource]="dataSource"
  class="mat-elevation-z8">
  <ng-container matColumnDef="category">
    <mat-header-cell *matHeaderCellDef>
      <mat-form-field appearance="outline">
        <input matInput placeholder="Category" [(ngModel)]="filterEntity.category">
      </mat-form-field>
    </mat-header-cell>
    <mat-cell *matCellDef="let element"> {{element.category}} </mat-cell>
  </ng-container>

  <ng-container matColumnDef="brand">
    <mat-header-cell *matHeaderCellDef>
      <mat-form-field appearance="outline">
        <input matInput placeholder="Product Brand" [(ngModel)]="filterEntity.brand">
      </mat-form-field>
    </mat-header-cell>
    <mat-cell *matCellDef="let element"> {{element.brand}} </mat-cell>
  </ng-container>

  <ng-container matColumnDef="availableSizes">
    <mat-header-cell *matHeaderCellDef>

      <mat-form-field class="example-chip-list">
        <mat-chip-list #chipList aria-label="Fruit selection">
          <mat-chip *ngFor="let size of filterEntity.availableSizes" [selectable]="true" [removable]="true"
            (removed)="remove(size)">
            {{size}}
            <mat-icon matChipRemove>cancel</mat-icon>
          </mat-chip>
          <input placeholder="Add Size" [matChipInputFor]="chipList"
            [matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="true"
            (matChipInputTokenEnd)="add($event)">
        </mat-chip-list>
      </mat-form-field>
    </mat-header-cell>
    <mat-cell *matCellDef="let element"> {{element.availableSizes}} </mat-cell>
  </ng-container>

  <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
  <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>

.ts

import { MatTableFilter } from 'mat-table-filter';
import { Component, OnInit } from '@angular/core';
import { MatTableDataSource, MatChipInputEvent } from '@angular/material';
import { COMMA, ENTER } from '@angular/cdk/keycodes';

export class Product {
  category: string;
  brand: string;
  availableSizes: Array<string>;
}

const PRODUCTS: Product[] = [
  {category: 'T-Shirt', brand: 'X', availableSizes: ['S', 'M', 'L', 'XL']},
  {category: 'T-Shirt', brand: 'Y', availableSizes: ['S', 'L', 'XL']},
  {category: 'T-Shirt', brand: 'Z', availableSizes: ['XL']},
  {category: 'Jean', brand: 'X', availableSizes: ['S', 'M', 'L', 'XL']},
  {category: 'Jean', brand: 'Y', availableSizes: ['S', 'M']},
  {category: 'Jean', brand: 'Z', availableSizes: ['S', 'M', 'L']},
  {category: 'Jean', brand: 'B', availableSizes: ['S', 'M', 'L']},
  {category: 'Jacket', brand: 'X', availableSizes: ['S', 'L', 'XL']},
  {category: 'Jacket', brand: 'Z', availableSizes: ['S']},
  {category: 'Pants', brand: 'X', availableSizes: ['S', 'M', 'L', 'XL']},
  {category: 'Pants', brand: 'Y', availableSizes: ['L', 'XL']},
  {category: 'Pants', brand: 'Z', availableSizes: ['S']},
  {category: 'Hat', brand: 'X', availableSizes: ['S', 'M', 'L']},
  {category: 'Skirt', brand: 'X', availableSizes: ['S', 'M', 'L', 'XL']},
  {category: 'Skirt', brand: 'Y', availableSizes: ['S', 'M', 'L']}
 ];

@Component({
  selector: 'app-array-filter',
  templateUrl: './array-filter.component.html',
  styleUrls: ['./array-filter.component.css']
})
export class ArrayFilterComponent implements OnInit {
  filterEntity: Product;
  filterType: MatTableFilter;
  displayedColumns: string[] = ['category', 'brand', 'availableSizes'];
  dataSource;
  readonly separatorKeysCodes: number[] = [ENTER, COMMA];

  add(event: MatChipInputEvent): void {
    const input = event.input;
    const value = event.value;

    if ((value || '').trim()) {
      this.filterEntity.availableSizes.push(value.trim());
    }

    // Reset the input value
    if (input) {
      input.value = '';
    }
  }

  remove(size: string): void {
    const index = this.filterEntity.availableSizes.indexOf(size);

    if (index >= 0) {
      this.filterEntity.availableSizes.splice(index, 1);
    }
  }

  ngOnInit() {
    this.filterEntity = new Product();
    this.filterEntity.availableSizes = new Array<string>(); // DO NOT FORGET TO INIT THE ARRAY
    this.filterType = MatTableFilter.ANYWHERE;
    this.dataSource = new MatTableDataSource(PRODUCTS);
  }
}