как остановить массив.функция фильтра

Я использую пользовательский фильтр поиска

HTML-код

 <input type="text" pInputText class="ui-widget ui-text" [(ngModel)]
 ="gloablFilterValue" (ngModelChange)="splitCustomFilter()" placeholder="Find" />

я использую ngModelChange() событие в поле поиска


globalSearch(realData, searchText, columns) {
        searchText = searchText.toLowerCase();
        return realData.filter(function (o) {
            return columns.some(function (k) {
                return o[k].toString().toLowerCase().indexOf(searchText) !== -1;
            });
        });
    }

    splitCustomFilter() {
    let columns =  
   ['PartNoCompleteWheel', 'DescriptionCompleteWheel', 'PartNoTyre', 'DescriptionTyre', 'PartNoRim', 'DescriptionRim','DeletedDateFromKDPStr', 'DateFromKDPStr', 'Status'];
   this.tyreAndRimList = this.globalSearch(this.tyreAndRimList, this.gloablFilterValue, columns); 
    }

на this.tyreAndRimList список значений для столбцов, указанных в column переменной.

фильтр работает хорошо! Но основная проблема заключается в том, что производительность фильтра очень низкая, а количество записей огромно(более 100 строк на каждая колонка)

, когда

фильтр работает хорошо, если я ввожу один символ (например,a). Но когда я набирал символ непрерывно, браузер зависал. причина в том, что фильтр запускает каждую типизацию в поле фильтра(из-за использования ngModelChange()// onchange() событие)

что я хочу!--26-->

Я хочу остановить фильтрацию, если пользователь непрерывно вводит в поле поиска. Как только пользователь остановите ввод, тогда только мне нужно начать фильтрацию.

что я сделал

Я попытался справиться с этим, используя setTimeout(). Но это просто ждать вызова фильтра на секунду. Он работает, если пользователь ввел только 2 или 3 символа непрерывно. Но если пользователь набирает более 7 или 8 или выше символов, он продолжает висеть в браузере. из-за многих обратных вызовов фильтра обрабатываются одновременно.

 setTimeout(() => //code of filtering ,1000);

вопрос

как остановить фильтрацию, когда пользователь непрерывно вводит значение и начинает фильтрацию после того, как пользователь остановил ввод?

Я работаю в angular-2 и typescript. Но этот вопрос не связан только с for angularjs или angular или JavaScript или typescript потому что я хочу идею, а не решение. Поэтому я добавлю эти теги для этого вопроса. Не снимай его. Спасибо

4 ответов


Debounce функции. Посмотрите, как подчеркивание делает это здесь:функция Debouncing с подчеркиванием.js.

затем вы должны создать debounced версию функции такой:

var globalSearchDebounced = _.debounce(globalSearch, 100, false);

Он будет вызывать только после того, как пользователь перестал печатать, по крайней мере, одной секунды.


невозможно прервать Array.filter метод. Основываясь на том, что вам нужно, вы можете справиться с этим следующим образом:

let timerId = null

function handleChange() {
  if(timerId) {
    clearTimeout(timerId)
  }

  timerId = setTimeout(() => /* Array.filter(...) */, 1000)
}

объяснение

есть переменная, которая будет содержать timerId вернулся из . Каждый раз, когда модель меняется handleChange функция будет вызвана (в этом примере). Функция проверяет, содержит ли переменная timerId установлен и содержит timerId, когда переменная содержит timerId на clearTimeout функция будет вызвана, чтобы очистить предыдущий тайм-аут после этого handleChange создает новый тайм-аут и назначает timerId (вернулся из setTimeout функция) к переменной.


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

в вашей глобальной функции поиска:

return Observable.of(/* filter here and return the filtered array */).debounceTime(1000)

в вашем списке (это должно быть где-то, я думаю)

<list-item *ngFor="let x of myFilteredResults | async">...</list-item>

и с помощью Subject to debounceTime.

private subject = new Subject<string>()
ngOnInit() {
        this.subject.debounceTime(300).subscribe(inputText => {
        this.gloablFilterValue = inputText;
        this.splitCustomFilter();   // filter method  
        });    
    }

теперь, когда я изменяю значение в this.gloablFilterValue "объект" с помощью события change. Он просто ждет окончания завершения события.