как остановить массив.функция фильтра
Я использую пользовательский фильтр поиска
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
функция) к переменной.
- документация
setTimeout
- документация
clearTimeout
без подчеркивания и без таймаута (который, кстати, вызовет весь угловой жизненный цикл), вы можете использовать наблюдаемый с асинхронным каналом и 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. Он просто ждет окончания завершения события.