我正在尝试对angular2进行异步验证,但是当我出于某种原因尝试输入某些内容时,反跳功能将无法正常工作。它会根据我的输入多次触发。同样在加载时,我的异步验证器也会被触发,因此将状态设置为待定,因此信息框显示checking...
这是我的实现方式:
HTML:
<div class="form-group d-flex col px-0">
<label for="coupon" class="col-2">coupon_code:</label
<div class="col-5 pl-4 pr-0">
<input
class="form-control"
id="coupon"
type="text"
name="coupon"
formControlName="coupon"
autocomplete="off"
/>
</div>
TS文件
表格:
initForm() {
const email = '';
const password = '';
const password_confirmation = '';
const doctor = '';
// const license = '';
const type = 'doctor';
const company_id = '';
const corporate_token = '';
const doctorLastName = '';
this.signUpForm = this.fb.group(
{
coupon: ['',[], this.couponAsyncValidation.bind(this)]
},
{
validator: this.signupFormValidator(),
}
);
}
异步验证码:
couponAsyncValidation(control: FormControl): Promise<any | null> | Observable<any | null> {
return new Promise( (res, rej) => {
control.valueChanges.pipe(
debounceTime(2000),
distinctUntilChanged(),
switchMap(value => this.userService.couponChecker(value)),
map( (q) => q ),
first()
).subscribe(
(d) => {
console.log(d)
d.is_coupon_valid ? res(null) : res({invalid: true})
}
)
})
}
couponAsyncValidation
将在加载时被触发,即使我没有触摸输入,状态也仍处于待处理状态。疯了
更新 管理工作状态。我已经检查了状态和未决状态以及是否脏了。
剩下的问题是debounceTimer无法正常工作
更新 我认为我缺少可观察的功能。你觉得怎么样?
更新 这是2秒后发送的请求的图片
你知道为什么去抖不起作用吗?
更新
这是在@jarek的帮助下进行的。
这是异步验证的完整代码
import { AbstractControl, AsyncValidatorFn } from '@angular/forms';
import { switchMap, map} from 'rxjs/operators';
import { UserService } from '../user/services/user.service';
import { Observable, timer, of } from 'rxjs';
export class AsyncValidator {
static couponValidator(miliSec: number, service: UserService): AsyncValidatorFn {
return (control: AbstractControl): Observable<any | null> => {
return timer(miliSec).pipe(
switchMap(() => {
if ( control.value ) {
return service.couponChecker(control.value);
}
// this one is needed because for some reason on loading, the signup page
// will immediately trigger this async call which sends a request to the backend
// even though user has not inputted anything.
// then sets the status of the form to pending thus resulting to an invalid form
return of({is_coupon_valid: true});
}),
map( (res) => res.is_coupon_valid ? null : res )
);
};
}
}
答案 0 :(得分:1)
答案 1 :(得分:0)
我有一个类似的情况,除了我的异步验证器直接在表单上...代码在下面,但它与您所需的内容不完全匹配。我怀疑您的核心问题是您的订阅控制值更改是不必要的,因为将其设置为验证器应该已经使该验证器在值更改时被调用。
validateExists(control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
{
return timer(500).pipe(
switchMap(() =>
this.service.checkThingExists(control.value.value1, control.value.value2).pipe(
tap(() => setTimeout(() => this.isValid.emit(this.form.get('parcel').valid))),
map(valid => (valid ? null : { notFound: true }))
)
)
);
}