У меня есть сложное приложение-калькулятор, написанное на Angular6, которое вычисляет результаты на основе нескольких входных данных в событии ngModelChange и напрямую отображает эти результаты в диаграммах. Расчет производится на стороне сервера. Теперь я хочу добавить время отладки, чтобы сервер не получал запрос при каждой нажатой клавише.
Мой метод расчета, который запускается в ngModelChange, выглядит так:
async calculate(){
if (this.checkInputs()){
try{
let returnDto = await this.webApiService.calculate(new CalculatorInputDto(this.model)).toPromise();
this.outputCalculate.emit(returnDto);
}
catch(e){
console.info(e);
}
}
И мой способ обслуживания:
calculate(dto: CalculatorInputDto): Observable<any> {
let url = this.baseUrl + "calculate";
return this.http.post(url, JSON.stringify(dto), this.options)
.pipe(
debounceTime(5000),
map((res => res.json())),
catchError(error => this.handleError(error))
);
}
Как видите, я уже пробовал использовать debounceTime (5000) в своем сервисе, но похоже, что ничего не изменилось.
Есть ли у кого-нибудь идеи, как я могу решить эту проблему?
Проверьте это: stackoverflow.com/questions/50275945/…
Я решил это сейчас с помощью этого вопроса: debounceTime & independentUntilChanged в angular 6
Поэтому я создал Viewchild для каждого входа и поместил их в массив. И в ngAfterViewInit я вызываю этот метод:
setInputEvent() {
let inputArray = this.fillViewChildsInArray();
for (let element of inputArray) {
this.input$ = fromEvent(element.nativeElement, 'input')
.pipe(
debounceTime(1000),
map((e: KeyboardEvent) => e.target['value'])
);
this.input$.subscribe((val: string) => {
this.calculate();
});
}
}
вы всегда можете реализовать это с помощью Subjects
, как показано ниже:
объявить тему:
customInput : Subject<string> = new Subject();
в вашем шаблоне:
(ngModelChange)='inputValueChanged($event)'
Итак, теперь прислушиваемся к событию:
inputValueChanged(event){
this.customInput.next(event);
}
Вам нужно будет подписаться на вашу тему следующим образом:
this.customInput.debounceTime(300).distinctUntilChanged().subscribe(value =>{
//value will have your input
});
(с этим ваш код будет выглядеть аккуратно и чисто, а также организованно)
Обновлено: с rxjs> = v6,
Полный пример можно найти здесь
import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged} from 'rxjs/operators';
this.customInput.pipe(debounceTime(300),distinctUntilChanged()).subscribe(value =>{
//value will have your input
});
вам нужен
debounceTime
в вашей подписке наkeypress
, а не здесь