javascript - debounceTime skickar förfrågan varje gång
Async Validator skickar en förfrågan till JSON varje gång man skriver i e-postformuläret. Det kontrollerar om e-posten finns för varje bokstav som skrivs. Hur kan man anropa servern och kontrollera en gång, inte för varje enskild bokstav?
isEmailExist(): AsyncValidatorFn {
return (control: AbstractControl): Observable<any> => {
return this.usersService.getUserByEmail(control.value).pipe(
debounceTime(2000),
map(users => {
if (users.some(user => user.email.toLowerCase() === control.value.toLowerCase())) {
return { isExist: true };
} else {
return null;
}
})
)
}
}
Svar #1
Operatorn debounceTime måste pipas efter en Observable som sänder keyup-händelser. Du kan använda fromEvent-operatorn för att uppnå det.
Svar #2
Merei, du kan använda {updateOn:'blur'}, se dokumentationen
Ett annat alternativ är att inte använda en validator och kontrollera isEmailExist vid skickning
Och ett annat alternativ är att du "kollar" e-posten i en debounceTime men om värdet ändras. Tänk dig att du har en variabel "kolla" och en kontroll
check=false;
control=new FormControl('',Validators.required,this.customValidator().bind(this))
koden bind(this) gör att du kan använda en variabel i din komponent, så din customValidator kan vara som
customValidator(){
return (control)=>{
if (!this.check) //if the variable in component is false return of(null)
return of(null)
//else you call to the service
return this.usersService.getUserByEmail(control.value).pipe(
map(users => {
if (users.some(user => user.email.toLowerCase() ===
control.value.toLowerCase())) {
return { isExist: true };
} else {
return null;
}
})
}
}
Nu, efter att ha definierat FormControl prenumererar du på valueChanges
this.control.valueChanges.pipe(debounceTime(300)).subscribe(_=>{
this.check=true;
this.control.updateValueAndValidity({emitEvent:false});
this.check=false;
})
I denna StackBlitz simulerar jag anropet till din tjänst med en dum funktion
