本文介绍了不使用 switchMap 调用 Angular 异步验证器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要检查用户输入的用户名是否唯一.因此,我为来自目标元素的每个 input 事件发送一个 HTTP 请求.而且,当然,我需要对这个操作进行去抖动,以便在特定时间间隔内为 X input 事件获得 1 个 HTTP 请求.
问题是 - 一旦我添加 switchMap 代码停止工作并且 switchMap 回调永远不会被调用.
没有 switchMap 的工作代码:

I need to check that username typed by user is unique. Thus, I'm sending an HTTP request for every input event from the target element. And, of course, I need to debounce this operation, so as to get 1 HTTP request for X input events following each other within a specific interval.
The problem is - as soon as I add switchMap the code stops working and switchMap callback is never called.
The working code without a switchMap:

public static createUniqueFieldValidator(
  target: 'username' | 'email' | 'phone',
  checker: (value: string) => boolean,
  userService: UserService
): AsyncValidatorFn {
  return (control: AbstractControl): Observable<NullableType<ValidationErrors>> => {
    if (!!control.value && checker(control.value)) {
      return fromPromise<SomeReturnedType>(
        userService.checkUnique({ [ target ]: control.value })
      ).pipe<NullableType<ValidationErrors>>(.......);
    }

    return of<null>(null);
  };
}

如果我添加一个 switchMap 它的回调永远不会被调用

If I add a switchMap its callback is never called

public static createUniqueFieldValidator(
  target: 'username' | 'email' | 'phone',
  checker: (value: string) => boolean,
  userService: UserService
): AsyncValidatorFn {
  return (control: AbstractControl): Observable<NullableType<ValidationErrors>> => {
    if (!!control.value && checker(control.value)) {
      // We do get here, I've checked
      return timer(300).pipe<NullableType<ValidationErrors>>(
        switchMap<number, Observable<NullableType<ValidationErrors>>>(
          (): Observable<NullableType<ValidationErrors>> => {
            console.log('SwitchMap');// The whole callback is never called
            // Here I'm supposed to make an HTTP request instead of returning a null
            return of<null>(null);
          }
        )
      );
    }

    return of<null>(null);
  };
}

如果我用

of<string>(control.value).pipe<NullableType<ValidationErrors>>(delay(), switchMap.......)

它也不起作用.
如果我用 switchMapOf 替换 switchMap 它可以工作但没有去抖动时间.

it doesn't work either.
If I replace switchMap with switchMapOf it works but without a debounce time.

推荐答案

看看 这个SO

好吧,您可以像这样创建验证器:

Well, you can create your validator like:

checkIfNotRegister(): AsyncValidatorFn {
    return (control: AbstractControl): Promise<ValidationErrors | null> |
                                       Observable<ValidationErrors | null> => {
      return timer(1000).pipe(switchMap(_=>this.service.getWebName(control.value).pipe(
        map(res => res ? { repeat: "name yet register" } : null)
      )))

    };
  }

但是您在 这个分叉的 stackblitz 消息正在验证......"显示输入的每次变化-如果将计时器更改 10000 毫秒,则这种效果更明显-

But you see in this forked stackblitz that the message "Validating.." is showed each change of the input -if you change the timer by 10000ms, this effect is more observable-

这篇关于不使用 switchMap 调用 Angular 异步验证器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 20:12