我需要用angular编写反应形式类型的异步验证器。 我已经实现了低谷承诺。但是问题是验证器会为每个击键击中服务器的每个击键触发。为实现防抖动功能,我已经为promise实现了setTimeout,但是我遇到的问题是它在我定义了特定的Millisecon之后触发。 最终,我在实现所有debounceTime的承诺中实现了Observable,但是我在这里面临的问题是debounceTime发出了所有事件。 例如:如果我在输入字段中键入'Prem',则以下代码会在超时发生时触发服务器四次。
如果在实现异步验证器时遇到任何问题,请澄清一下。
//Latest code
static hasDuplicateEmail(formControl: FormControl) {
return new Promise((resolve, reject) => {
return new Observable(observer =>
observer.next(formControl.value)).pipe(
debounceTime(600),
distinctUntilChanged(),
switchMap((value) => {
//server side
return MotUtil.fetch('checkForRegisterEmail', {e: formControl.value});
})
).subscribe((res) => {
return (JSONUtil.isEmpty(res)) ? resolve(null) : resolve({duplicate: true});
});
});
}
debounceTime应该如文档中所述工作。
答案 0 :(得分:2)
您正在尝试以困难的方式进行处理。验证程序采用参数- AbstractControl 。 AbstractControl具有属性-valueChanges
,该属性返回formControl中的更改流。因此,您在此处添加debouceTime
,然后再执行其他操作,最后将此流返回给FormControl:
hasDuplicateEmail(control: AbstractControl) {
return control.valueChanges.pipe(
debounceTime(600),
switchMap(e =>
this.http.get('checkForRegisterEmail', {e}).pipe(
map((res: any) => JSONUtil.isEmpty(res) ? null : { duplicate: true })
)
)
)
}
正如您所注意到的,我使用 HttpClient ,因为它是您在Angular中进行HTTP调用的方式(它设计为在流而不是Promises上工作)