Как применить несколько фильтров в таблице угловых материалов? - PullRequest
1 голос
/ 19 апреля 2019

Привет, есть таблица данных с 4 столбцами - имя, возраст, отметки, школа. Теперь я хочу применить фильтр для каждого из столбцов. Фильтр отлично работает индивидуально. Но я не могу объединить результаты фильтра - например, я не могу отфильтровать Имя с отметками> 90 и из школы 'abc'.

Я пробовал что-то подобное, но это не сработало.

applyFilter(filterValue: string) {
    console.log("Filter is applied upon:",this.dataSource)
    let initialDataSource = this.dataSource;
    this.dataSource.filter = filterValue.trim().toLowerCase();
    this.filteredDataSource = this.dataSource.filteredData
    this.filterVal = this.dataSource.filter;
    if(this.filterVal.length != 0){
      this.dataSource = new MatTableDataSource(this.filteredDataSource);
      this.dataSource.filter = filterValue.trim().toLowerCase();
    }else{
      this.dataSource = initialDataSource;
      this.dataSource.filter = filterValue.trim().toLowerCase();
      this.filteredDataSource = this.dataSource.filteredData
    }
  }

Приведенная выше функция выполняет фильтрацию, но когда я очищаю значение фильтра, данные таблицы не изменяются. Также оно не изменяется при удалении символа.

Ответы [ 2 ]

0 голосов
/ 10 июля 2019

Вот немного более элегантное решение.

Объявите интерфейс TableFilter для удобства:

interface ITableFilter {
  column: string;
  value: any;
}

Функция предиката фильтра вызывается один раз в строке (!) При применении фильтрации: если предикат возвращает значение true, текущая строка будет включена в отфильтрованные результаты. Поэтому мы будем перебирать массив фильтров и возвращать false, если в одном из столбцов есть несоответствие.

Замените свой фильтр источника данныхПредикат следующим пользовательским:

  setDataSource() {
    this.dataSource = new MatTableDataSource(this.yourData);
    this.dataSource.filterPredicate = this.customFilterPredicate;
  }


  private customFilterPredicate(data: any, filters: ITableFilter[]): boolean {        
    for (let i = 0; i < filters.length; i++) {
      const fitsThisFilter = data[filters[i].column].toLowerCase().includes(filters[i].value);
      if (!fitsThisFilter) {
        return false;
      }
    }
    return true;
  }

После этого вы можете применить свой фильтр следующим образом:

// implement some relevant logic to build the filters array
const filter: any = [{column: 'name', value: 'foo'}, {column: 'description', value: 'bar'}];
// this is how you apply a filter
this.dataSource.filter = filter;

Немного глупо, что нам нужно установить фильтры как 'any'; но функция фильтра ожидает строку, и другого способа обойти ее нет.

0 голосов
/ 19 апреля 2019

Я смог понять это!

  1. Получить исходные данные из источника данных в ngOnInit.

ngOnInit() {
    
    this.httpService.get('./assets/emp.json').subscribe(
      data => {
        this.headers = data;
        this.dataSource = new MatTableDataSource(this.headers);
        this.initialData = this.dataSource.data;
        this.dataSource.paginator = this.paginator;
        // console.log(data);
      },
      (err: HttpErrorResponse) => {
        console.log(err.message);
      }
    );
  }
  1. Запишите метод applyFilter () как -

 applyFilter(filterValue: string) {
    let filteredData;
    // let initialData = this.dataSource.data;
    console.log("iniital data", this.initialData)
    if (filterValue.length != 0) {
      console.log("data source:", this.dataSource)
      this.dataSource.filter = filterValue.trim().toLowerCase();
      filteredData = this.dataSource.filteredData;
      this.dataSource.data = filteredData
      console.log("Filtered Data", filteredData);
    } else {
      this.dataSource.data = this.initialData
      console.log("Its empty")
    }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...