Как отфильтровать MatTable в угловой без filterPredicate - PullRequest
2 голосов
/ 09 июля 2019

У меня есть MatTable, который я хочу отфильтровать с помощью values Я сохраняю данные от пользователя input Я могу проверить, что значение соответствует данным, но я не знаю, как отфильтровать таблицу без использованияfilterPredicare, так как использование другого создаст мне проблему с дублированием.

Это мой компонент NgOnInit:

 ngOnInit() {
    this.marinService.getAllContainers().subscribe((result) => {
     //Data
      this.dataSource = new MatTableDataSource(result);
      //Paginator
      this.dataSource.paginator = this.paginator;
      //AutoFilter Form 1st page
      this.clientType = this.route.snapshot.queryParamMap.get('clientType');
      this.storageType= this.route.snapshot.queryParamMap.get('storageTypes');
      console.log('The Client name is : '+this.clientType+'  '+'The storage Facility is : '+this.storageType);
      this.tableFilter();
      //snapShot Filter
      //CheckBoxFilter
      this.dataSource.filterPredicate = (data: Container, filter: any) => {
        return filter.split(',').every((item: any) => data.SOG_MCOLH.indexOf(item)!== -1);
      };
      this.filterCheckboxes.subscribe((newFilterValue: any[]) => {
        this.dataSource.filter = newFilterValue.join(',');
      });
      });
  }

Это мой function:

  tableFilter(){
    var data : Container = this.dataSource;
    var newData: any[];
    if(data.LQOCH_SHM_LOEZI_QTSR = this.clientType){
      console.log(data.LQOCH_SHM_LOEZI_QTSR);
    }else{
      console.log("Hi Not working")
      return this.dataSource;
    }
  }

Я пытался использовать тот же «метод фильтрации», что и в filterPrediacte, но он не сработал.

1 Ответ

1 голос
/ 09 июля 2019

На мой взгляд, было бы лучше изменить filterPredicate() в соответствии с вашими потребностями. mat-table оптимизирован для повышения производительности, поэтому создание собственного фильтра для таблицы без использования filterPredicate() может привести к проблемам с производительностью. У меня есть рабочий пример этого на stackblitz .

В моем примере я создаю фильтр как объект следующего формата

{
  columnName: Array(filterValues),
  ...
}

(поскольку в этом поле вы можете фильтровать определенные столбцы на основе определенного значения, и в одном столбце может быть несколько фильтров)

Я использую функцию updateFilter() для изменения фильтра на основе выбранного флажка. Это просто добавит фильтр к объекту фильтра, если флажок установлен, и удалит его из объекта фильтра, если флажок снят. Этот объект фильтра затем будет передан в фильтр mat-table в виде строки (поскольку filterPredicate() принимает только строковые значения)

updateFilter(column: string, filter: string) {
  if (!this.filterValues.hasOwnProperty(column)) {
    this.filterValues[column] = [filter];
  } else {
    this.filterValues[column].includes(filter) ?
    this.filterValues[column] = this.filterValues[column].filter(filterValue => filterValue !== filter) :
    this.filterValues[column].push(filter);
  }

  this.applyFilter();
}

В filterPredicate() проанализируйте объект фильтра и отфильтруйте данные на основе этого объекта. Я использую переменную conditions, так как может быть установлено несколько флажков одновременно (нам нужно будет передать все данные, которые удовлетворяют всем выбранным условиям. Попробуйте установить все флажки в примере). Для любого пользовательского фильтра (например, показать все данные с прогрессом> 90%) вы можете добавить условие. Я добавил пользовательский фильтр для имени, поскольку столбец содержит как имя, так и фамилию, а я фильтрую только по имени (подмножеству имени).

this.dataSource.filterPredicate = ((data: UserData, filter: string): boolean => {
  const filterValues = JSON.parse(filter);
  let conditions = true;

  for (let filterKey in filterValues) {
    if (filterKey === 'name') {
      conditions = conditions && data[filterKey].trim().toLowerCase().indexOf(filterValues[filterKey]) !== -1;
    }
    else if (filterValues[filterKey].length) {
      conditions = conditions && filterValues[filterKey].includes(data[filterKey].trim().toLowerCase());
    }
  }

  return conditions;
});

Наконец, чтобы активировать фильтр. При установке флажка просто позвоните updateFilter() вместе с columnName для фильтрации и значением. Например, чтобы показать красные цвета, вызовите updateFilter('color', 'red'), где 'color' - имя столбца, а 'red' - значение фильтра.

Редактировать : Существуют разные способы сделать то, что вы упомянули в комментариях. Вы можете установить значение для вашего флажка и добавить переменную ссылки на шаблон . Ниже #color указана переменная вашего шаблона. Это позволяет вам получить доступ к значению этого флажка в html, используя color.value

<mat-checkbox value="blue" (change)="updateFilter('color', color.value)" #color>Show blue colors</mat-checkbox>

Если у вас есть значение, определенное в вашем компоненте, и вы передаете его в флажок, используя [value]. Вы можете либо снова использовать ссылочную переменную шаблона для передачи данных, либо просто передать само значение.

компонент

name: string = 'Amelia';

HTML

// No interpolation required when passing the value to the function.
<mat-checkbox [value]="name" (change)="updateFilter('name', name)">Show all first name - Amelia</mat-checkbox>

Проверьте обновленный stackblitz , чтобы увидеть это в действии.

...