【发布时间】:2020-05-01 18:26:14
【问题描述】:
我在构建调用 firebase 数据库的验证器时遇到问题。代码如下,我们来看看验证器。假设我在数据库中有数组 ['track1','track2']。当trackName 字段填充track1 值时,控制台返回a,这是它应该的。但我发现,existingTrack 错误没有出现。而不是这个错误,我在 FormGroup 中得到了下面提到的错误:
errors:
closed: false
destination: SafeSubscriber {closed: false, _parent: null, _parents: null, _subscriptions: null, syncErrorValue: null, …}
isStopped: false
syncErrorThrowable: true
syncErrorThrown: false
syncErrorValue: null
_parent: null
_parents: null
_subscriptions: [MapSubscriber]
__proto__: Object
我尝试在表单生成器中将validator 更改为asyncValidator,但在这样做之后,验证器完全停止工作。我认为订阅和管道词可能有问题,我不确定何时使用哪个。
组件代码:
constructor(public fb: FormBuilder, private dataService: DataService) {}
ngOnInit() {
this.form = this.fb.group({
newTrack: this.fb.control(false, Validators.required),
trackName: this.fb.control(''),
trackLength: this.fb.control('', [Validators.pattern('^[0-9]{1,}.[0-9]{1,2}$')]),
trackSelect: this.fb.control(''),
time: this.fb.control('', [Validators.required, Validators.pattern('^[0-9]{1,}:[0-9]{2}$')]),
date: this.fb.control('', [Validators.required])
},
{validator: this.tracksDataValidator.bind(this)});
}
tracksDataValidator(group: FormGroup) {
const newTrack = group.get('newTrack').value;
const trackSelect = group.get('trackSelect').value;
const trackName = group.get('trackName').value;
const trackLength = group.get('trackLength').value;
return this.dataService.isTrackTaken(trackName).subscribe((res: any[]) => {
if (newTrack === true) {
if (res.length > 0) {
console.log('a');
return {existingTrack: true};
}
if (trackName === '' || trackLength === '') {
return {newTrackNotFilled: true};
}
} else {
if (trackSelect === '') {
return {noTrackSelected: true};
} else {
return null;
}
}
});
}
数据服务
constructor(private db: AngularFireDatabase) {}
isTrackTaken(trackName: string) {
return this.db.list('/tracks').valueChanges()
.pipe(map(tracks => tracks.filter((track: Track) => track.name === trackName)));
}
编辑:
我尝试以与 alligator.io 网站上完全相同的方式创建验证器,我将表单构建器更改为
this.form = this.fb.group({
newTrack: this.fb.control(false, Validators.required),
trackName: this.fb.control('', [Validators.required], this.trackDataValidator.bind(this)),
trackLength: this.fb.control('', [Validators.pattern('^[0-9]{1,}.[0-9]{1,2}$')]),
trackSelect: this.fb.control(''),
time: this.fb.control('', [Validators.required, Validators.pattern('^[0-9]{1,}:[0-9]{2}$')]),
date: this.fb.control('', [Validators.required])
});
和验证者
trackDataValidator(control: FormControl) {
return this.dataService.isTrackTaken(control.value).subscribe((res: any[]) => {
return (res.length > 0) ? {existingTrack: true} : null;
});
}
DataService 代码相同。在trackName 字段中输入每个字母后,都会出现此错误:
ERROR Error: Expected validator to return Promise or Observable.
at toObservable (forms.js:1466)
at Array.map (<anonymous>)
at FormControl.asyncValidator (forms.js:1446)
at FormControl._runAsyncValidator (forms.js:4100)
at FormControl.updateValueAndValidity (forms.js:4053)
at FormControl.setValue (forms.js:4692)
at updateControl (forms.js:3299)
at DefaultValueAccessor.onChange (forms.js:3271)
at DefaultValueAccessor._handleInput (forms.js:419)
at Object.eval [as handleEvent] (NewTrainingComponent.html:14)
【问题讨论】: