角度过滤器不会一次只过滤每一列

问题描述

INTRO

我试图实现我的Angular列过滤器在过滤掉一列后不显示以前过滤的结果。当我在列过滤器中选择更多项目时,它还能继续过滤结果。

假设我从“名称”列中选择了一个名称,它会很好地过滤(确实如此),但是,一旦我选择了一个不同的列过滤器(例如“项目”),它就会添加之前被过滤掉的其他所有内容并过滤我需要(过滤项目),与“项目活动”相同,它只是添加了越来越多的已过滤项目,但保留了旧的已过滤垃圾

我只是不知道如何实现一种机制来阻止过滤器向我的过滤列中添加错误的项目。

代码

我的 HTML 中有5列:

<mat-table #table [dataSource]="dataSource" matSort matSortActive="work_date" matSortDirection="asc">
            <ng-container matColumnDef="create_by">
                <mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
                <mat-cell *matCellDef="let log"> {{ log.create_by }} </mat-cell>
            </ng-container>

            <ng-container matColumnDef="project_id">
                <mat-header-cell ng-repeat="data in filtered = (list | filter: search)" *matHeaderCellDef
                    mat-sort-header>
                    Project ID </mat-header-cell>
                <mat-cell *matCellDef="let log"> {{ getSecondarrayItem(log.project_id)?.name }} </mat-cell>
            </ng-container>

            <ng-container matColumnDef="project_activity_id">
                <mat-header-cell *matHeaderCellDef mat-sort-header> Project Activity ID </mat-header-cell>
                <mat-cell *matCellDef="let log"> {{ getPAItem(log.project_activity_id)?.name }} </mat-cell>
            </ng-container>

            <ng-container matColumnDef="work_date">
                <mat-header-cell *matHeaderCellDef mat-sort-header> Work date </mat-header-cell>
                <mat-cell *matCellDef="let log"> {{formatingDate(log.work_date)}} </mat-cell>
            </ng-container>

            <ng-container matColumnDef="hours">
                <mat-header-cell *matHeaderCellDef mat-sort-header> Hours </mat-header-cell>
                <mat-cell *matCellDef="let log"> {{log.hours}} </mat-cell>
            </ng-container>

            <ng-container matColumnDef="minutes">
                <mat-header-cell *matHeaderCellDef mat-sort-header> Minutes </mat-header-cell>
                <mat-cell *matCellDef="let log"> {{log.minutes}} </mat-cell>
            </ng-container>

            <ng-container matColumnDef="notes">
                <mat-header-cell *matHeaderCellDef mat-sort-header> Additional notes </mat-header-cell>
                <mat-cell *matCellDef="let log"> {{log.notes}} </mat-cell>
            </ng-container>

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

这将是我在组件中的 filter createFilter 是所有用于过滤列的逻辑和主过滤器逻辑发生的主要焦点。

filterChange(filter,event) {
    //let filterValues = {}

    if (this.hasFilter) {
      // second filter
      console.log("second filter");
      this.filterValues[filter.columnProp] = event.target.value.trim().toLowerCase().toString();
      console.log(this.filterValues);

      this.dataSource.filter = JSON.stringify(this.filterValues);
      console.log(this.dataSource.filter);

    } else {
      console.log("first filter");
      this.filterValues[filter.columnProp] = event.target.value.trim().toLowerCase().toString();
      console.log(this.filterValues);

      this.dataSource.filter = JSON.stringify(this.filterValues);
      console.log(this.dataSource.filter);
      this.hasFilter = true;
    }
  }

createFilter() {
    if (this.hasFilter) {
      // second filter - multi-layer filter

    } else {

      let filterFunction = function (data: any,filter: string): boolean {
        let searchTerms = JSON.parse(filter);
        let isFilterSet = false;
        for (const col in searchTerms) {
          console.log(searchTerms);
          console.log(col);
          if (searchTerms[col].toString() !== ' ') {
            isFilterSet = true;
          } else {
            delete searchTerms[col];
          }
        }

        console.log(searchTerms);

        let nameSearch = () => {
          let found = false;
          if (isFilterSet) {
            for (const col in searchTerms) {
              console.log(searchTerms[col]);

              if (searchTerms[col] == data[col].toString().toLowerCase() && isFilterSet) {
                found = true;
                console.log(this.nameSearch + " nameSearch");
                console.log(this.filterFunction + " filterFunction");
              } else {
                if (filterFunction == undefined) {
                  return found == true;
                }
              }
            }
            return found
          } else {
            return true;
          }
        }
        return nameSearch()
      }
      return filterFunction
    }
  }

我的数据源是我的数据库,它与数据库的连接非常好,并且一次过滤一列。

解决方法

老实说,我的解决方案可能不是最好的,但这是我在一个项目中找到的解决方案:

  1. 对于每列,使用反应形式创建输入并订阅其valueChange事件。

  2. 创建一个键:值对象以按列存储您的搜索词。看起来应该像{column1:columnFilter,column2:filter} ...等。

  3. 根据您在valueChange事件中捕获的内容,使用过滤条件填充它。

  4. 通过您自己的过滤功能覆盖数据源过滤器

  5. 确保您的新过滤方法基本上是通过使用开关盒来根据列应用过滤器。