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.log(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)を試しましたが、何も変わっていないようです。
誰かが私がこの問題を解決する方法を知っていますか?
以下のように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の場合
this.customInput.pipe(debounceTime(300),distinctUntilChanged()).subscribe(value =>{
//value will have your input
});
私はこの質問の助けを借りて今のところこれを解決しました: debounceTime&distinctUntilChanged in 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();
});
}
}