繁体   English   中英

Angular 5 Debounce自定义异步验证器

Angular 5 Debounce Custom Async Validator

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我创建了一个自定义的异步验证器,该验证器使用服务来针对服务器验证电子邮件。 但是,这意味着每次输入字符都会打服务器,这是不好的。 在这里,我已经遵循了几个无法开始工作的答案。

我的验证者:

import {FormControl, NG_ASYNC_VALIDATORS, Validator} from 
'@angular/forms';
import { Http } from '@angular/http';
import {Directive, forwardRef} from "@angular/core";
import {ValidateEmailService} from "../services/validate-email.service";
import {UserService} from "../services/user.service";

@Directive({
  selector: '[appEmailValidator]',
  providers: [
    { provide: NG_ASYNC_VALIDATORS, useExisting: forwardRef(() => EmailValidator), multi: true }
  ]
})
export class EmailValidator implements Validator {
  public validateEmailService: ValidateEmailService;

  constructor(
    private _http: Http,
    private _userService: UserService
  ) {
    this.validateEmailService = new ValidateEmailService(this._http, this._userService);
  }

  validate(c: FormControl) {
    return new Promise(resolve => {
      this.validateEmailService.validateEmail(c.value)
        .subscribe((res) => {
          console.log(res);
          if (res.valid) {
            resolve(null);
          } else {
            resolve({
              valid: {
                valid: false
              }
            });
          }
        });
      })
    }
}

它本身可以很好地工作,但是一旦我尝试向其添加某种形式的去抖动功能,我最终就将其破坏了。

我已经尝试过从这个问题的答案,我得到错误的Type X is not assignable to type 'Observable<any>'等。

我通过使用setTimeout接近了,但最终所做的只是停止功能。

我的最终目标是仅在输入未更改约600 ms时运行验证器,但会确定每600-2000 ms仅验证一次。

为了更加清楚,可以使用ValidateEmailServicevalidateEmail方法:

public validateEmail(email: string) {

  let validateEmail = new ValidateEmail(email);

  return this._http.get(
    this.getUrl(validateEmail),
    this.getOptionArgs())
    .map((response: Response) => Object.assign(new UserEmailVerification(), response.json().UserEmailVerification));

}
2 个回复

我还没有看到实现为指令的异步验证器,而是分配给表单控件的验证器功能。

这是我用于类似情况的示例验证器:

import { Injectable } from '@angular/core';
import { AbstractControl, AsyncValidatorFn } from '@angular/forms';
import { Observable, timer, of } from 'rxjs';
import { switchMap, map } from 'rxjs/operators';

import { MembershipsService } from '@app/memberships/memberships.service';

@Injectable()
export class MembershipsValidators {

  constructor (
    private membershipsService: MembershipsService,
  ) {}

  checkMembershipExists(email?: string): AsyncValidatorFn {
    return (control: AbstractControl): Observable<{ [key: string]: any } | null> => {
      if (control.value === null || control.value.length === 0) {
        return of(null);
      }
      else if (email && email === control.value) {
        return of(null);
      }
      else {
        return timer(500).pipe(
          switchMap(() => {
            return this.membershipsService.lookupMember(control.value).pipe(
              map(member => {
                if (!member) {
                  return { noMembership: { value: control.value } };
                }

                return null;
              })
            );
          })
        );
      }
    };
  }

}

导入并应用到表单控件中,如下所示:

this.form = this.formBuilder.group({
  memberEmail: new FormControl('', {
    validators: [ Validators.required, Validators.pattern(regexPatterns.email) ],
    asyncValidators: [ this.membershipsValidators.checkMembershipExists() ],
  }),
});

这样,直到满足同步验证器的要求时,异步验证器才会触发。

您可以在您的承诺内创建一个Observable来完成反跳操作。

这种逻辑可能不会被剪切和粘贴,但可以使您接近。

import {distinctUntilChanged, debounceTime, switchMap} from 'rxjs/operators';

 validate(c: FormControl) {
  return new Promise(resolve => {
    new Observable(observer => observer.next(c.value)).pipe(
      debounceTime(600),
      distinctUntilChanged(),
      switchMap((value) => { return this.validateEmailService.validateEmail(value) })
    ).subscribe(
      (res) => {
        console.log(res);
        if (res.valid) {
          resolve(null);
        } else {
          resolve({
            valid: {
              valid: false
            }
          });
        }
      }
    )
  })
}
1 Angular 7:自定义异步验证器

我正在尝试为我的注册表单创建一个自定义异步验证器,用于检查是否已存在电子邮件。 如果电子邮件不存在,后端将返回404;如果确实存在,则后端返回200(无法更改此旧代码)。 我找到了几个教程,但没有找到使用最新的rxjs库的教程。 我创建了这个Validation类: 并在我的t ...

2 Angular 4-使用异步自定义验证器

我有以下代码: HTML: Component.ts: 在component.ts的内部构造函数中: 我正在尝试将此异步验证器绑定到反应形式,但是它不起作用。 我想在工作流程窗体内使用plicatorWorkflowValidator,并在找到重复的工作流程时触发 ...

3 Angular自定义异步验证器保持待定状态

我有一个自定义验证器,用于验证用户电子邮件是否唯一。 我已经搜索了关于stackoverflow和Internet的相关主题,但是没有帮助 当我以表单形式发送输入(发送请求)时,请求将保持待处理状态,并且无法解析。 我已经在邮递员中测试了后端,它的工作正常,问题出在客户端或角度 ...

4 formArray 的 Angular 异步自定义验证器

我有一个表单,其中包含我正在使用 formArray 的金额动态字段。 用户可以生成金额的多个字段。 我想要的是计算所有动态字段中的总值,并在超过总数时显示错误消息。 问题是当我循环遍历 FormArray 并更改值,然后在解析时返回一个承诺,但它只显示第一个字段的验证错误。 下面是 Stack ...

5 如何在 Angular 中创建自定义异步验证器?

我创建了一个后端验证器,我想以如下方式从前端调用它: 所以验证器应该将两个参数作为输入。 我的页面由许多行组成,每行有四个输入字段:名字、姓氏、电子邮件和电话。 我没有在 ts 文件中使用任何 FormControl 或 FormGroup ,我只有通过ngModel将对象绑定到 html 。 ...

6 Angular 2异步自定义验证器

我正在尝试实现异步自定义验证,我有如下的验证类 在我的组件中 我将它添加到表单控件中 您可以看到我正在尝试在验证器中注入服务。 然后在我的组件中使用验证器函数我必须创建验证器的对象并使用它的方法。 我已经调试过,看到this._auth_service属性在我的验证器 ...

8 如何在 Angular 中使用自定义异步验证器正确显示验证错误

现场演示 正如您在此演示中看到的,当您在旧密码输入字段中键入字符时,带有“旧密码不匹配”错误的 div 元素会不断在浏览器中呈现,从而导致用户体验不佳。 这个元素: 每次我在输入字段中输入字符时都会不断渲染。 我使用了 setTimeout() 函数来模拟对服务器的调用。 任何帮助将不胜感 ...

9 异步自定义验证器方法

我的 c# 项目中有一个自定义验证器,它将检查来自cloud firestore 的重复电子邮件,但我意识到服务器端的异步方法导致自定义验证器无法正常工作,帮助....谢谢。 客户端: 服务器端: ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2021 STACKOOM.COM