gpt4 book ai didi

validation - 为什么 distinctUntilChanged 在 angular 的异步验证器中不起作用

转载 作者:行者123 更新时间:2023-12-05 01:37:14 24 4
gpt4 key购买 nike

当我出于某种原因在表单输入上按下一个键时,异步验证器没有检测到 distinctUntilChanged,它仍然发送 API 请求。例如,如果我按 35,删除 5,然后再次添加 5,它仍然会发送请求。这是代码:(我几乎什么都试过了,但还是不行)

validateSomeNumber(control: FormControl): Observable<any> | Promise <any> {
this.isSubmitBtnDisabled = true;
return control.valueChanges.pipe(
debounceTime(1000),
distinctUntilChanged(),
switchMap((value) => {
return this.apiService.someApiRequest({ 'to_number': control.value }).pipe(
map(res => {
console.log(res);
if (res.success) {
// console.log(res);
this.isSubmitBtnDisabled = false;
return null;
} else {
// console.log(res);
this.isSubmitBtnDisabled = true;
return{ 'invalidCharacters': true };
}
}),
);
}),
first()
);
}

最佳答案

默认情况下,每次值更改后都会调用 validateSomeNumber

如果您在每次值更改时返回它

return control.valueChanges.pipe(
debounceTime(1000),
distinctUntilChanged(),
...
)

您正在为每次值更改创建一个新的值更改 Observable。例如,如果你输入四个字符,你最终会得到四个独立的 Observable,每个 Observable 发射一个字符,而不是一个 Observable 发射四次。所以 debounceTimedistinctUntilChanged 只会影响您在特定值更改时创建的 Observable,而不是整个值更改过程。如果它们只影响发射一次的 Observable,那么它们显然不会像您希望的那样工作。

应该直接返回http请求

validateSomeNumber(control: FormControl): Observable<any> | Promise <any> {
this.isSubmitBtnDisabled = true;
return this.apiService.someApiRequest({ 'to_number': control.value }).pipe(
map(..),
);
}

限制请求频率

选项 1:updateOn

防止在每次值更改时执行 http 请求 Angular recommends changing the updateOn property to submit or blur .

使用模板驱动的表单:

<input [(ngModel)]="name" [ngModelOptions]="{updateOn: 'blur'}">

react 形式:

new FormControl('', {updateOn: 'blur'});

{updateOn: 'blur'} 只会在您的输入失去焦点时执行验证器。

选项 2:模拟 debounceTime 和 distinctUntilChanged

如果表单值发生变化,Angular 会自动取消订阅之前由 AsyncValidator 返回的 Observable。这允许您使用 timer 模拟 debounceTime。要模拟 distinctUntilChanged,您可以跟踪最后一个请求项并自己进行相等性检查。

private lastRequestTerm = null;

validateSomeNumber(control: FormControl): Observable<any> | Promise <any> {
this.isSubmitBtnDisabled = true;
// emulate debounceTime
return timer(1000).pipe(
// emulate distinceUntilChanged
filter(_ => control.value != this.lastRequestTerm),
switchMap(() => {
this.lastSearchTerm = control.value;
return this.apiService.someApiRequest({ 'to_number': control.value });
}),
map(..)
);
}

关于validation - 为什么 distinctUntilChanged 在 angular 的异步验证器中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61140859/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com