我正在尝试将SwitchMap与异步验证程序结合使用,我创建了以下异步验证程序,但先前请求的SwitchMap取消行为无效!
我在这里缺少什么?
static emailValidator(userService: UsersService) {
return (control: AbstractControl) => {
return of(control.value).pipe(
switchMap(
value => userService.validateEmail(value)
),
map(
(res: {isValid: boolean}) => {
return res.isValid ? null : {username: false};
}
),
catchError(
(err) => {
return of({username: false});
}
)
);
};
}
答案 0 :(得分:0)
您每次都在创建一个新的可观察对象,因此源不再发射,因此也不会切换。无论如何,这都是多余的,因为异步验证器会自动处理取消操作,只需执行以下操作:
static emailValidator(userService: UsersService) {
return (control: AbstractControl) => {
return userService.validateEmail(control.value).pipe(
map(
(res: {isValid: boolean}) => {
return res.isValid ? null : {username: false};
}
),
catchError(
(err) => {
return of({username: false});
}
)
);
};
}
闪电战证明了这一点:https://stackblitz.com/edit/angular-xqjgbe?file=src/app/app.component.ts
如果您想完全避免使用新值发送请求(将其反跳)...这很容易;
static emailValidator(userService: UsersService) {
return (control: AbstractControl) => {
return timer(300).pipe( // timer will debounce for you
switchMapTo(userService.validateEmail(control.value)),
map(
(res: {isValid: boolean}) => {
return res.isValid ? null : {username: false};
}
),
catchError(
(err) => {
return of({username: false});
}
)
);
};
}
答案 1 :(得分:0)
您需要使用of(control.value)
来代替使用control.valueChanges
创建可观察对象:
static emailValidator(userService: UsersService) {
return (control: AbstractControl) => {
return control.valueChanges.pipe(
switchMap(
value => userService.validateEmail(value)
),
map(
(res: {isValid: boolean}) => {
return res.isValid ? null : {username: false};
}
),
catchError(
(err) => {
return of({username: false});
}
)
);
};
}