【问题标题】:How do I display a custom error message from a custom validator function in angular 4?如何在角度 4 中显示来自自定义验证器函数的自定义错误消息?
【发布时间】:2017-12-26 12:48:58
【问题描述】:

请考虑以下自定义验证器函数,该函数在后端调用 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 视图中返回无效时,我不知道如何向用户显示适当的消息。如果这个函数没有返回一个可观察的,我会做这样的事情:

<div *ngIf="form.controls['categoryName'].errors?.categoryNameUnique">
    This category name is already taken
</div>

但是,由于这是一个返回的 observable,errors 对象具有 Observable 公开的属性,即operatorsource,而不是我要返回的自定义对象 ({categoryNameUnique: false})。

任何帮助将不胜感激。

更新 1:

大家好,在尝试了其他一些事情之后,我能够弄清楚自己的问题。

我是这样设置表单验证的:

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)])]
    });
}

所需的 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)]),
            Validators.composeAsync([this.categoryNameUnique.bind(this)])]
    });
}

【问题讨论】:

  • 这个&lt;div *ngIf="form.controls['categoryName'].errors?.categoryNameUnique"&gt; 应该可以正常工作,它对你来说表现如何?
  • @Maximus,categoryNameUnique 没有出现在我的错误对象中。相反,errors 对象包含 Observable 的属性:operatorsource。如果我检查这两个属性,它不会显示与我从可观察对象中传回的 categoryNameUnique 自定义错误对象相关的任何内容。
  • 奇怪,你能设置一个 plunker 吗?
  • 另外,您的validate 方法看起来如何?
  • 感谢@Maximus,我已经更新了我的原始帖子,描述了问题所在以及我如何解决它。

标签: javascript angular validation typescript


【解决方案1】:

我认为您的问题可能是您如何将异步验证器应用于控件。根据您对form.controls.categoryName 的使用,我假设您正在使用表单生成器来创建表单。在这种情况下,您需要提供异步验证器作为组参数数组中的第三个参数,如下所示:

this.form = this.formBuilder.group({
  categoryName: ["", [], [categoryNameUnique]]
});

这样设置后,你应该可以在错误中看到你所期望的。

我首选的显示自定义验证错误的方式如下:

<div *ngIf="form.controls.categoryName.hasError('categoryNameUnique')">
    The category name is not unique!
</div>

【讨论】:

  • 谢谢@Dhraz...当我自己想出来的时候你回答了。无论如何,我感谢您的帮助,并将您的回答标记为正确答案。
  • 没问题,希望对遇到同样问题的人有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
  • 1970-01-01
  • 2018-08-09
  • 2019-09-27
  • 1970-01-01
  • 1970-01-01
  • 2018-02-08
相关资源
最近更新 更多