如何在多个列下拉列表上过滤Angular Mat Table

时间:2020-08-18 07:20:26

标签: angular-material mat-table

我正在尝试对每个列标题中的下拉值过滤角垫表。我可以过滤任何一个下拉值,但不能使用多个下拉值。是否可能有多个下拉菜单?这是我尝试过的。

HTML

          <table mat-table  [dataSource]="listData">
            <ng-container matColumnDef="Name">
             <th mat-header-cell *matHeaderCellDef>Name
             <br>
               <mat-form-field>
               <select matNativeControl (change)="onChangeName($event.target.value)">
                 <option *ngFor="let name of names" [value]="name">
                   {{name | titlecase}}
                 </option>
                </select>
              </mat-form-field>
             </th>
             <td mat-cell *matCellDef="let row; let rowIndex = index" >
             {{row.name}}
             </td>
          </ng-container>
          <ng-container matColumnDef="location ">
              <th mat-header-cell *matHeaderCellDef>Location
                <mat-form-field>
                    <select matNativeControl (change)="onChangeLocation($event.target.value)">
                      <option *ngFor="let location of locations" [value]="location">
                        {{track | titlecase}}
                    </option>
                    </select>
                  </mat-form-field>
             </th>
             <td mat-cell *matCellDef="let row; let rowIndex = index" >
             {{row.location}}
             </td>
           </ng-container>
         </table>

TS文件

          ngOnInit(): void {
          this.listData=new MatTableDataSource(res);
          }

         onChangeName(name){
          this.selectedName=name;
          if(this.selectedLocation){
          this.listData.filter=name+this.selectedLocation;
          }
          else{
          this.listData.filter=name;
          }
         }

        onChangeLocation(location){
          this.selectedLocation=location;

         if(this.selectedName){
         this.listData.filter=location+this.selectedName;
         }
         else{
         this.listData.filter=location;
         }

1 个答案:

答案 0 :(得分:0)

这有点棘手,但希望我能帮助您走上正确的轨道。 默认过滤器谓词的工作方式(简化)是它检查所传递的数据对象(即row)的任何属性是否包含所传递的过滤器。

这对您不起作用,因此您将覆盖数据源的filterPredicate。但是,这仍然不能完全解决您的问题-过滤器仅接受字符串对象,并且最好您要传递自定义的“过滤器对象”。要解决它,您可以编写您的DataSource的自定义实现,或在将其作为过滤器传递之前序列化过滤器对象,然后在filterPredicate中反序列化它。

一个简单的实现是(根据您的示例):

  private filter: any = {};

  ngOnInit(): void {
    this.listData = new MatTableDataSource(res);
    this.listData.filterPredicate = (data, filter): boolean => {
      const filterObject = JSON.parse(filter);

      for (const filterProperty in filterObject) {
        if (!Object.prototype.hasOwnProperty.call(filterObject, filterProperty)) {
          continue;
        }

        const searchTerm: string = filterObject[filterProperty] ? filterObject[filterProperty].trim().toLowerCase() : '';
        const rowValue: string = data[filterProperty] ? data[filterProperty].trim().toLowerCase() : '';
        return rowValue.indexOf(searchTerm) > -1;
      }

      return true;
    };
  }

  onChangeName(name) {
    this.updateDataSourceFilter('name', name);
  }

  onChangeLocation(location) {
    this.updateDataSourceFilter('location', location);
  }


  private updateDataSourceFilter(propertyName: string, value: any): void {
    this.filter[propertyName] = value;

    this.listData.filter = JSON.stringify(this.filter);
  }

这是从我的脑海中冒出来的,因此它可能无法编译-但应向您提供如何自行实现此功能的基本思路。