Фильтрация данных таблицы для нескольких столбцов Angular 10

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

В моем html я ниже

             <tr>
             <td *ngFor="let t of tableHeader">
               <input type="text" [id]="t.key" (keyup)="inputChange($event)">
               </td>
            </tr>

Мой файл TS, как показано ниже

    public inputChange(value) {
    var prevData = this.dataSource;

    if (this.selectedId == '') {
      prevData = this.result;
    }
    else if (this.selectedId != '' && this.selectedId != value.target.id) {
      prevData = this.result;
    }

     if (this.selectedId != '' && filterValue.target.value == '') {   
       this.result = prevData;
       return;
     }
   
    this.selectedId = value.target.id;
    this.inputValue = value.target.value;

    var filteredData = this.result.filter(x => x[this.selectedId] && x[this.selectedId].toString().toLowerCase().includes(this.inputValue.toLowerCase()));
    this.result = filteredData;
    }

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

Ожидается: вместо источника данных отображать ранее отфильтрованные данные.


person Yugant Pardeshi    schedule 30.11.2020    source источник
comment
Что вы подразумеваете под удалением значения? Сделать поле ввода пустым или нажать клавишу возврата?   -  person abney317    schedule 30.11.2020
comment
Я сделал демонстрацию stackblitz, не могли бы вы сказать, в чем проблема? stackblitz.com/edit/   -  person Owen Kelvin    schedule 30.11.2020
comment
yes @ abney317, нажав Backspace, он должен отобразить ранее отфильтрованные данные   -  person Yugant Pardeshi    schedule 01.12.2020


Ответы (1)


Для этого я бы использовал следующие шаги, используя rxjs

  1. Определите datasource как Observable
dataSource = [
    {
      firstname: "James",
      lastname: "Amstrong",
      othernames: "Angel",
      age: 35
    },
    {
      firstname: "John",
      lastname: "Peter",
      othernames: "Ava",
      age: 43
    },
...
]

Мы преобразуем это datasource в наблюдаемое, используя of из 'rxjs'

  1. Определите фильтр как Observable
   tableHeader = [
    {
      key: "firstname"
    },
    {
      key: "lastname"
    },
    ...
  ];
 filterKeyValues = this.tableHeader.map(({ key }) => ({ key, value: "" }));
 filterSubject$ = new BehaviorSubject(this.filterKeyValues)
  filter$ = this.filterSubject$.asObservable()

Это просто генерирует Observable со структурой

Observable<[{ key: firtname, value: ''}, { key: lastname, value: ''}, ...]>
  1. Объедините два и верните новый Observable в качестве новых отфильтрованных данных.
dataSource$ = combineLatest([
    this.filter$, of(this.dataSource)
  ]).pipe(
    map(([filter, dataSource]) => 
     dataSource.filter(item => 
        filter.every((value) => 
          (new RegExp(String(value.value).toLowerCase())).test(String(item[value.key]).toLowerCase())
          
        )
      )
    )
  )
  1. Определите обработчик для inputChange
  public inputChange(event: any, key) {
    this.filterKeyValues.find(({key: testKey}) => testKey === key).value = event.target.value
    this.filterSubject$.next(this.filterKeyValues)
  }
  1. Используйте async для отображения содержимого
<table>
    <tr>
        <td *ngFor="let t of tableHeader">
            <input type="text" [id]="t.key" (keyup)="inputChange($event, t.key)">
           </td>
    </tr>
  <tr *ngFor="let item of  dataSource$ | async">
    <td>{{ item.firstname }}</td>
    <td>{{ item.lastname }}</td>
    <td>{{ item.othernames }}</td>
    <td>{{ item.age }}</td>
  </tr>
</table>

Мы вызываем следующее значение. это вызовет обнаружение изменений, и datasorce$ Observable будет переоценен, что вызовет обновление в пользовательском интерфейсе

Я сделал демонстрацию здесь чтобы проиллюстрировать этот подход

person Owen Kelvin    schedule 30.11.2020
comment
именно этого я и хотел, спасибо @Owen Kelvin. - person Yugant Pardeshi; 01.12.2020