简体   繁体   English

Angular > 材质表中的过滤器 x 2

[英]Angular > filter x 2 in Material table

In Angular, I use a Material table with expanded rows and I want to filter it with 2 filters: the first one on "RequestId" and the second on "originSupplyToDestination".在 Angular 中,我使用带有扩展行的 Material 表,我想用 2 个过滤器对其进行过滤:第一个在“RequestId”上,第二个在“originSupplyToDestination”上。 The filter on "RequestId" works. “RequestId”上的过滤器有效。 But with "Origin", I miss something.但是对于“Origin”,我想念一些东西。

table-tree.html表树.html

<div class="filter">
  <span>
  <h5 class="requestid">Request ID</h5>
  <input type="text" [(ngModel)]="requestFilter" />
</span>
</div>

<div class="filter">
<span>
<h5 class="origin">Origin</h5>
<input type="text" [(ngModel)]="originFilter" />
</span>
</div>

<table mat-table [dataSource]="filteredRequests" multiTemplateDataRows class="mat-elevation-z8">
  <ng-container matColumnDef="{{column}}" *ngFor="let column of columnsToDisplay">
    <th mat-header-cell *matHeaderCellDef>{{columnNames[column]}}</th>
    <td mat-cell *matCellDef="let element">
      {{element[column]}}
    </td>
  </ng-container>

  <ng-container matColumnDef="expandedDetail">
    <td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplay.length">
      <div class="example-element-detail" [@detailExpand]="element == expandedInfo ? 'expanded' : 'collapsed'">
        <div class="example-element-position">{{element.creationDate}}</div>
        <div class="example-element-description">
          {{element.serialNumberProductRefToSupply}}
        </div>
        <div class="example-element-description">
          {{element.serialNumberOriginSupplyToDestination}}
        </div>
      </div>
    </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
  <tr mat-row *matRowDef="let element; columns: columnsToDisplay;" class="example-element-row"
    [class.example-expanded-row]="expandedInfo === element" (click)="expandedInfo = element"></tr>
  <tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
</table>

table-tree.ts表树.ts

import { Component, OnInit } from '@angular/core';
import {
  animate,
  state,
  style,
  transition,
  trigger
} from '@angular/animations';

@Component({
  selector: 'table-tree',
  styleUrls: ['table-tree.css'],
  templateUrl: 'table-tree.html',
  animations: [
    trigger('detailExpand', [
      state(
        'collapsed',
        style({ height: '0px', minHeight: '0', display: 'none' })
      ),
      state('expanded', style({ height: '*' })),
      transition(
        'expanded <=> collapsed',
        animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')
      )
    ])
  ]
})
export class TableTree implements OnInit {
  dataSource = MoveOrderData;

  expandedInfo: MoveOrderAuthorizations;
  requestFiltered = '';
  filteredRequests: MoveOrderAuthorizations[];
  originFiltered = '';
  filteredOrigin: MoveOrderAuthorizations[] = [];

  ngOnInit() {
    this.filteredRequests = this.dataSource;
    this.filteredOrigin = this.dataSource;
  }

  // Request Id Filter
  get requestFilter(): string {
    return this.requestFiltered;
  }
  set requestFilter(value: string) {
    console.log(value);
    this.requestFiltered = value;
    this.filteredRequests = this.performRequestIdFilter(value);
  }

  performRequestIdFilter(filterBy: string): MoveOrderAuthorizations[] {
    filterBy = filterBy.toLocaleLowerCase();
    this.filteredRequests = this.dataSource.filter(
      (request: MoveOrderAuthorizations) => request.requestId.includes(filterBy)
    );
    return !!filterBy && this.filteredRequests.length > 0
      ? this.filteredRequests
      : this.dataSource;
  }

    // Origin Filter
    get originFilter(): string {
      return this.originFiltered;
    }
    set originFilter(value: string) {
      console.log(value);
      this.originFiltered = value;
      this.filteredOrigin = this.performOriginFilter(value);
    }
  
    performOriginFilter(filterBy: string): MoveOrderAuthorizations[] {
      filterBy = filterBy.toLocaleLowerCase();
      this.filteredOrigin = this.dataSource.filter(
        (origin: MoveOrderAuthorizations) => origin.originSupplyToDestination.includes(filterBy)
      );
      return !!filterBy && this.filteredOrigin.length > 0
        ? this.filteredOrigin
        : this.dataSource;
    }

  columnsToDisplay = [
    'creationDate',
    'requestId',
    'issue',
    'requestType',
    'managedBy',
    'ProductRefToSupply',
    'originSupplyToDestination'
  ];

  columnNames = {
    creationDate: 'Creation Date',
    requestId: 'Request ID',
    issue: 'Issue',
    requestType: 'Request Type',
    managedBy: 'Managed by',
    ProductRefToSupply: 'Product ref to supply',
    originSupplyToDestination: 'Origin supply to Destination'
  };

  responseColumnsToDisplay = ['moveorderId', 'originDestination', 'status'];
  subColumnNames = {
    moveorderId: 'Move Order ID',
    originDestination: 'Origin Destination',
    status: 'Status'
  };
}

export interface MoveOrderAuthorizations {
  creationDate: string;
  requestId: string;
  issue: string;
  requestType: string;
  managedBy: string;
  ProductRefToSupply: string;
  originSupplyToDestination: string;
}

const MoveOrderData: MoveOrderAuthorizations[] = [
  {
    creationDate: `01/01/2021`,
    requestId: '139322',
    issue: ``,
    requestType: `Evacuation`,
    managedBy: `AGV`,
    ProductRefToSupply: `ML132345XO1211321AND11432001`,
    originSupplyToDestination: `SA-11EOL-LN001`
  },
  {
    creationDate: `01/01/2021`,
    requestId: '254982',
    issue: `Destination not found`,
    requestType: `Supply`,
    managedBy: `AGV`,
    ProductRefToSupply: `ML132345XO1211321AND11432002`,
    originSupplyToDestination: `RE-11WIP-11E03`
  }
];

For each filter, I wrote a method with getter and setter to filter the data which are displayed but it doesn't work with the second filter.对于每个过滤器,我使用 getter 和 setter 编写了一个方法来过滤显示的数据,但它不适用于第二个过滤器。

You can go and see the table on Stackblitz > https://stackblitz.com/edit/tab-tree-filter-aa4vhx?file=app/table-tree.ts你可以去 Stackblitz > https://stackblitz.com/edit/tab-tree-filter-aa4vhx?file=app/table-tree.ts上查看表格

Thanks :)谢谢 :)

EDIT: Last question.编辑:最后一个问题。 I'd like to add a chevron before the date.我想在日期前加一个 V 形标志。 When the row expands, the chevron turn down.当行展开时,人字形向下。 My problem is the chevron is in front of every row elements...我的问题是雪佛龙在每一行元素的前面......

Your approach will not work, since you're not using your filteredOrigin anywhere in your template.您的方法将不起作用,因为您没有在模板中的任何地方使用filteredOrigin Anyway, even if you did, you're not joining your both filters to filter a single array of items.无论如何,即使您这样做了,您也不会加入两个过滤器来过滤单个项目数组。

You can make your dataSource a MatTableDataSource instead of an array (docs here ).您可以将dataSource MatTableDataSource而不是数组( 此处为文档)。 It has basic extensions used for filtering, paging, etc.它具有用于过滤、分页等的基本扩展。

Once you do that, you can create a custom filterPredicate - ie a function that is responsible for filtering records based on passed filter value.一旦你这样做了,你就可以创建一个自定义的filterPredicate - 即一个函数,它负责根据传递的filter值过滤记录。

Then, it will automatically fill the table with the filteredData , while still holding the initial data.然后,它会自动填写表格与filteredData ,同时仍持有的初始数据。

It's a bit trickier with two filtering fields, since filter value only accepts string.两个过滤字段有点棘手,因为filter值只接受字符串。 To overcome that, you can simply stringify your filter object, and then parse it again inside the filterPredicate function.为了克服这个问题,您可以简单地将过滤器对象字符串化,然后在filterPredicate函数中再次解析它。

Here's a stackblitz example based on your code.这是基于您的代码的stackblitz 示例

Note that in your version, when filtering returned 0 rows, it would display all the rows.请注意,在您的版本中,当过滤返回 0 行时,它将显示所有行。 Have in mind that this is VERY counterintuitive since you don't know if anything was filtered, or all rows are displayed.请记住,这是非常违反直觉的,因为您不知道是否过滤了任何内容,或者显示所有行。 I've changed that logic in my version to simply NOT display any rows if all the rows are filtered out.我已经在我的版本中更改了该逻辑,如果所有行都被过滤掉,则不显示任何行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM