实际上我遇到了这个问题。
我已经创建了一个自定义异步验证程序来检查是否使用了用户名。这是我绑定它的地方:
'name': ['',[Validators.required, Validators.minLength(4), Validators.minLength(4)], this.asyncName.bind(this)],
这是我的验证员:
asyncName(control: FormControl) {
this.names$ = this.af.database.list('/usernames')
.map (name => {
name.filter(name => {
if (name.name.toLowerCase() === control.value.toLowerCase()) {
console.log("Username taken");
return {
valid: false
};
} else {
console.log("Username available");
return {
valid: true
};
}
})
});
return this.names$;
};
所以这个验证器有效。如果使用用户名,则记录“Username taken”,否则记录“Username available”。
我的问题:返回语句不起作用。当我订阅表单的状态时,它仍然是“待定”而不是“有效”或“无效”。 Angular2认为验证仍在运行。
有没有人知道如何根据observables创建有效的return或resolve语句?
也许我自己订阅并使用resolve()函数执行某些操作。但我所有的尝试都没有奏效。
提前致谢!!!
答案 0 :(得分:3)
您可以尝试.first()
以确保在第一个事件发生后关闭可观察信息:
asyncName(control: FormControl) {
this.names$ = this.af.database.list('/usernames').first()
.map(...
不确定这是否是实际问题。
答案 1 :(得分:0)
我有类似的问题。就我而言,我有类别列表,我想检查类别名称是否唯一。这是我的验证器:
export class CategoryFormComponent {
constructor(
private firebase: AngularFireDatabase
) {}
categoryExists(control: AbstractControl) {
return this.firebase.database
.ref(`categories/${this.uid}`) // user's uid
.orderByChild('name')
.equalTo(control.value)
.once('value')
.then((snapshot) => {
return snapshot.val() ? { categoryExists: true } : null;
});
}
}
正如您所看到的,您可以在数据库上进行搜索(性能更高),然后使用一次返回Promise。