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