Вызов методов фильтрации в строке после предыдущего завершения

У меня есть компонент турбо-таблицы primeng. Мне нужно применить несколько фильтров к таблице.
От родителя, которого я вызываю
myTable.doFilter(first_values); myTable.doFilter(second_values); один за другим

На компоненте child (turbo-table) фактический фильтр применяется как
doFilter(...filter_values...){ this.pTable.filter(...filter_values...); } doFilter(...filter_values...){ this.pTable.filter(...filter_values...); } Проблема заключается в том, что второй фильтр применяется до того, как первый закончен и вызывает неожиданные результаты.
Как я могу вызвать фильтры после завершения предыдущего фильтра. Событие испускается после завершения фильтра, но я не могу найти способ использовать его.

Parent.ts

 fetchList(searchData) {
        this.ratesTable.reset();
        this.ratesDataSource = [];
        this.programService.fetchList(searchData)
          .then(
            (response) => {

              this.ratesDataSource = response.rates;
              this.doTermFilter();
              this.doLoanFilter();
            })
          .catch((error) => {
            console.error("from ts" + error);
          });
      }
    doTermFilter(){
    this.doFilter({ filterValue: _termFilters, columnField: "COL1", filterMethod: "in" });
    }
doLoanFilter(){
    this.doFilter({ filterValue: _loanFilters, columnField: "COL7", filterMethod: "in" });
    }

child.ts (турбо-таблица)

 doFilter(doFilterInput: { filterValue: any[], columnField: any, filterMethod: any }) {
    this.pTable.filter(doFilterInput.filterValue, doFilterInput.columnField, doFilterInput.filterMethod);
    }

Буду признателен за любую оказанную помощь. Спасибо

Ответы

Ответ 1

Это исходный код метода фильтра:

filter(value, field, matchMode) {
    if(this.filterTimeout) {
        clearTimeout(this.filterTimeout);
    }

    if (!this.isFilterBlank(value)) {
        this.filters[field] = { value: value, matchMode: matchMode };
    } else if (this.filters[field]) {
        delete this.filters[field];
    }

    this.filterTimeout = setTimeout(() => {
        this._filter();
        this.filterTimeout = null;
    }, this.filterDelay);
}

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

Ссылка: https://github.com/primefaces/primeng/blob/master/src/app/components/table/table.ts

Ответ 2

Посмотрите мой ответ на вопрос " Как фильтровать сложные структурированные данные Json в Angular 6". Я использую шаблон rxjs Observable для реализации реактивного/функционального/декларативного решения для фильтрации таблицы, которая, по моему мнению, соответствует вашему прецеденту...? (это сложно сказать без кода)

Ответ 3

Я не знаю, как работает ваша система событий на столе, но в целом вы сможете сделать что-то вроде этого:

myTable.pTableReference.onFilterEvent(someData => myTable.doFilter(second_values));
myTable.doFilter(first_values);

Вы также можете попытаться обезопасить свой подход, основанный на событиях:

// child

doFilter(values): Promise<any> {
  return new Promise<any>((resolve, reject) =>
    this.pTable.onFilterEvent(resolve);
    try {
      this.pTable.filter(values);
    }
    catch(e) {
      reject(e);
    }
  )
}

// parent

myFilterFunction() {
  myTable.doFilter(first_values).then(result => myTable.doFilter(second_data));
}

// or using the 'await' keyword
async myFilterFunction() {
  await myTable.doFilter(first_values);
  await myTable.doFilter(second_data);
}

Или идите еще дальше и превратите его в Observables.

Как я уже сказал в начале, все зависит от того, как работает ваша система событий, и от того, как вы регистрируете обратные вызовы для них...

Надеюсь, это немного поможет :-)

Ответ 4

Theres специальный синтаксис для работы с асинхронными функциями в Javascript, называемый async/await. Его удивительно легко понять и использовать. В твоем случае:

async applyFilters() {
  await this.doTermFilter();
  this.doLoanFilter();
}

Ключевое слово await заставит JavaScript подождать, пока doTermFilter() не doTermFilter() а затем вызовет doLoanFilter().

fetchList(searchData) {
...
this.ratesDataSource = response.rates;
this.applyFilters();

Асинхронная функция

Ждите