请考虑以下自定义验证程序函数,该函数在后端调用API以获取某些数据,针对当前表单输入检查它们,如果当前表单输入是重复值,则返回错误:
//check to see if the new category name entered is already in the system
categoryNameUnique(c: FormControl) {
let categoryNameAlreadyExists: boolean = false;
//get list of current categories from the server.
return this.inventoryCategoryService.getAll().map(items => {
for (let item of items) {
if (item.Name == c.value) {
categoryNameAlreadyExists = true;
break;
}
}
if (categoryNameAlreadyExists) {
//name is not unique
return { categoryNameUnique: false }
}
//not a duplicate, all good
return null;
});
}
你会看到这个函数正在返回一个observable(因为我必须回到后端服务器来获取一些数据来进行验证)。验证器就像一个魅力,没有问题。但是,当我的相应HTML视图中的验证程序返回无效时,我不知道如何向用户显示相应的消息。如果这个函数没有返回一个observable,我会做类似的事情:
<div *ngIf="form.controls['categoryName'].errors?.categoryNameUnique">
This category name is already taken
</div>
但是,由于这是一个返回的observable,因此错误Object具有Observable公开的属性,即operator
和source
,而不是我返回的自定义对象({{1 }})。
任何帮助都将不胜感激。
更新1:
大家好,在尝试了其他一些事情后,我能够找出自己的问题。
我正在设置我的表单验证:
{categoryNameUnique: false}
必需的minLength和maxLength验证器是同步的,但我的自定义验证器categoryNameUnique是异步的,因此应该单独组成。我将设置更改为以下内容,现在一切正常:
constructor(private fb: FormBuilder, private router: Router, private inventoryCategoryService: InventoryCategoryService) {
this.form = fb.group({
'categoryName': [null, Validators.compose([Validators.required, Validators.minLength(3), Validators.maxLength(50), this.categoryNameUnique.bind(this)])]
});
}
答案 0 :(得分:2)
我认为您的问题可能就是您如何将异步验证器应用于控件。根据您对form.controls.categoryName
的使用情况,我假设您正在使用formbuilder来创建表单。在这种情况下,您需要提供异步验证器作为组params数组中的第3个参数,如下所示:
this.form = this.formBuilder.group({
categoryName: ["", [], [categoryNameUnique]]
});
在设置完毕后,您应该能够按预期在错误中看到它。
我显示自定义验证错误的首选方法如下:
<div *ngIf="form.controls.categoryName.hasError('categoryNameUnique')">
The category name is not unique!
</div>