问题描述
我需要检查用户输入的用户名是否唯一.因此,我为来自目标元素的每个 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 异步验证器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!