Angular6 ngModelChange 中的去抖时间
Debouncetime in Angular6 ngModelChange
我有一个用 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),但似乎没有任何改变。
有谁知道我该如何解决这个问题?
我在这个问题的帮助下暂时解决了这个问题:
所以我为每个输入创建了一个 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,
可以找到完整的例子here
import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged} from 'rxjs/operators';
this.customInput.pipe(debounceTime(300),distinctUntilChanged()).subscribe(value =>{
//value will have your input
});
我有一个用 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),但似乎没有任何改变。
有谁知道我该如何解决这个问题?
我在这个问题的帮助下暂时解决了这个问题:
所以我为每个输入创建了一个 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,
可以找到完整的例子here
import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged} from 'rxjs/operators';
this.customInput.pipe(debounceTime(300),distinctUntilChanged()).subscribe(value =>{
//value will have your input
});