我正在玩angular 2表单异步验证,一切都很好,但后来我意识到在输入字段内的每一次按键都会对服务器进行ajax调用,这对服务器来说不好,我尝试了很多方法,但都不起作用。所以请帮助我如何处理这个问题。
form: FormGroup;
username: FormControl;
password: FormControl;
constructor(private fb: FormBuilder, private http: Http) {
this.username = new FormControl("", Validators.compose([
Validators.required,
SignupValidators.CannotContainSpace]),
this.usernameShouldBeUnique.bind(this));
this.password = new FormControl("", Validators.compose([Validators.required]));
this.form = fb.group({
username: this.username,
password: this.password
});
}
异步验证方法:
usernameShouldBeUnique(formControl:FormControl) {
return new Promise(resolve => {
let params = new URLSearchParams();
params.set('username', formControl.value);
this.http.get('http://localhost:1667/api/users/signup/namecheck', { search: params })
.subscribe(data => resolve(null),
error => resolve({ usernameShouldBeUnique: true })
);
});
}
您可以使用Rxjs运算符,称为debounceTime或delay,并区分Untilchanged,如下所示,
usernameShouldBeUnique(formControl:FormControl) {
let params = new URLSearchParams();
params.set('username', formControl.value);
return this.http.get('http://localhost:1667/api/users/signup/namecheck', { search: params })
// .delay(300) <---- check this according to your need
.debounceTime(300) //<---- wait for 300ms pause in events
.distinctUntilChanged() //<---- ignore if next search term is same as previous
.subscribe(data => resolve(null),
error => resolve({ usernameShouldBeUnique: true })
);
}
根据这个很好的答案,您可以使用非常方便的setTimeout
和clearTimeout
来延迟您的请求:
private timeout;
usernameShouldBeUnique(formControl: FormControl) {
MY_DELAY = 500;
clearTimeout(this.timeout);
return new Promise(resolve => {
let params = new URLSearchParams();
params.set('username', formControl.value);
this.timeout = setTimeout(() => {
this.http.get('http://localhost:1667/api/users/signup/namecheck', {
search: params
})
.subscribe(data => resolve(null),
error => resolve({
usernameShouldBeUnique: true
})
);
}, MY_DELAY);
});
}
MY_DELAY
将导致请求在继续之前等待500毫秒以不再进行验证更改。