debounceTime 每次发送请求

debounceTime send request each time

每次在电子邮件表单中键入时,异步验证器都会向 JSON 发送请求。它检查现有的电子邮件,以输入每个字母。如何调用服务器并检查一次,而不是每个字母都检查一次?

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;
            }
        })
     ) 
   }
  }

Merei,可以使用{updateOn:'blur'},见the docs

另一种选择是不使用验证器并在提交时检查 isEmailExist

另一种选择是您在 debounceTime 中“检查”电子邮件,但值发生变化。 假设您有一个变量“check”和一个控件

  check=false;
  control=new FormControl('',Validators.required,this.customValidator().bind(this))

bind(this)使您可以使用组件的变量,因此您的 customValidator 可以像

  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;
          }
     })
    }
  }

现在,在定义 FormControl 之后您订阅 valueChanges

this.control.valueChanges.pipe(debounceTime(300)).subscribe(_=>{
  this.check=true;
  this.control.updateValueAndValidity({emitEvent:false});
  this.check=false;
})

this stackblitz我用傻瓜函数模拟调用你的服务

debounceTime 运算符必须在发出 keyup 事件的 Observable 之后用管道传输。 您可以使用 fromEvent 运算符来实现。