Javascript 角度异步验证未打印错误消息
以下是我的组件:Javascript 角度异步验证未打印错误消息,javascript,angular,typescript,Javascript,Angular,Typescript,以下是我的组件: import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { HttpService } from './http.service'; import { ProjectidService } from './projectid.service'; @Component({ sel
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { HttpService } from './http.service';
import { ProjectidService } from './projectid.service';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
projectDetailForm: FormGroup;
public submitted = false;
constructor(private fb: FormBuilder, private projectidvalidator: ProjectidService) { }
ngOnInit() {
this.projectDetailForm = this.fb.group({
projectid: ['', [Validators.required], [this.projectidvalidator.validate.bind(this.projectidvalidator)]],
projectname: ['name', Validators.required]
})
}
get f() { return this.projectDetailForm.controls; }
get validprojectid() { return this.projectDetailForm.get('projectid'); }
onSubmit(form: FormGroup) {
this.submitted = true;
// stop here if form is invalid
if (this.projectDetailForm.invalid) {
return;
}
console.log('Valid?', this.projectDetailForm.valid); // true or false
console.log('ID', this.projectDetailForm.value.projectid);
console.log('Name', this.projectDetailForm.value.projectname);
}
}
我的服务:
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { delay, tap, debounceTime } from 'rxjs/operators';
@Injectable()
export class HttpService {
constructor() { }
checkProjectID(id): Observable<any> {
// Here I will have valid HTTP service call to check the data
return of(true)
}
}
从'@angular/core'导入{Injectable};
从'rxjs'导入{可观察的};
从“rxjs/operators”导入{delay,tap,debounceTime};
@可注射()
导出类HttpService{
构造函数(){}
checkProjectID(id):可观察的示例您可以使用以下方法进行操作:
从“rxjs”导入{timer};
....
返回计时器(500)。管道(
开关映射(()=>{
如果(!control.value){
返回(空);
}
返回此。\u httpService.checkProjectID(control.value).pipe(
地图(isTaken=>{
控制台日志(isTaken);
如果(isTaken){
返回{noproject:true};
}否则{
返回null;
}
})
);
})
);
真正的问题是,我自己也遇到过,您订阅了值更改,但需要等待状态更改返回。
它在执行调用时处于“挂起”状态。
debounce/timer/…只是“hack”,因为您永远不知道何时返回值
声明一个变量:
this.formValueAndStatusSubscription: Subscription;
在你的
this.formValueAndStatusSubscription =
combineLatest([this.form.valueChanges, this.form.statusChanges]).subscribe(
() => this.formStatusBaseOnValueAndStatusChanges = this.form.status
);
别忘了删除订阅异步验证中最重要的一点如文档中所述
返回的可观察对象必须是有限的,这意味着它必须在
某个点。要将一个无限的可观测值转换为一个有限的可观测值,管道
通过过滤运算符(如first、last、take、,
或者直到
因此,基本上你可以使用例如take(1)
,它将获取第一次发射,然后标记可观察的完成
return control.valueChanges.pipe(
debounceTime(500),
take(1),
switchMap(() =>
this._httpService.checkProjectID(control.value).pipe(
map(isTaken =>
isTaken ? { noproject: true } : null
)
))
)
shreyas为什么不使用debouceTime并使用控件。valueChange
?是否有相同的具体原因?我认为您的方法与解释一致,因此当调用时间超过500毫秒时,此代码将无法按预期工作。是否有任何方法实现debouceTime
和distinctUntilChange
我来看看
this.formValueAndStatusSubscription =
combineLatest([this.form.valueChanges, this.form.statusChanges]).subscribe(
() => this.formStatusBaseOnValueAndStatusChanges = this.form.status
);
return control.valueChanges.pipe(
debounceTime(500),
take(1),
switchMap(() =>
this._httpService.checkProjectID(control.value).pipe(
map(isTaken =>
isTaken ? { noproject: true } : null
)
))
)