【发布时间】:2019-12-06 21:34:36
【问题描述】:
我正在尝试在 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 秒后发送的请求的图像
知道为什么 debounce 不起作用吗?
更新
现在在 @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 )
);
};
}
}
【问题讨论】:
-
每次值改变时都会调用异步验证器。因此,每次值更改时,您都会创建一个新的 observable 并订阅它。每次值变化时都会发出这个 observble。
-
@JBNizet 我已经知道了。抱歉,如果我的问题不清楚。但是为什么即使我设置了
debounceTime它也会阻止它在设定的时间过去之前进行投射 -
我错过了对 first() 的调用。
标签: angular observable angular2-observables