使用Angular 2 FormBuilder
,当我有一个具有验证的表单控件并且我关注然后不聚焦时,将触发验证规则并且控件将设置错误。
如何针对blur
或focusout
?
我尝试了这个指令,但它确实有效,但它非常hacky并且除非input
字段是设置了[formGroup]
属性的表单的子节点,否则它也不起作用,否则我得到一个Error: No provider for NgControl!
错误:
import { Directive, Input, HostListener } from '@angular/core';
import { NgControl } from '@angular/forms';
@Directive({
selector: 'input'
})
export class InputDirective {
constructor(private formControl: NgControl) {}
@HostListener('focusout')
onFocusOut() {
this.formControl.control.markAsUntouched(true);
}
}
是否有某种方法可以为表单构建器设置全局规则?
这个错误很烦人,因为如果我点击一个输入字段,然后尝试单击它下面的按钮而没有先输入足够的数据使该字段“有效”,那么点击该按钮我将出现验证错误它会向下移动屏幕,从而阻止点击按钮,因为它向下移动太远而无法使点击工作。
例如:
正如您在上面的GIF中所看到的,当我单击输入字段时,会触发验证器并在字段上设置错误,从而显示错误消息并弄乱我的按钮单击。
当然,这是我自己的问题,因为我有错误消息,但我想一起禁用focusout
上的错误检查。
答案 0 :(得分:2)
您可以使用ngIf控制验证消息的显示时间。像这样:
<span class="help-block" *ngIf="(productNameVar.touched ||
productNameVar.dirty || product.id !== 0) &&
productNameVar.errors">
<span *ngIf="productNameVar.errors.required">
Product name is required.
</span>
<span *ngIf="productNameVar.errors.minlength">
Product name must be at least three characters.
</span>
</span>
或者,由于您使用的是反应形式,您可以编写通用验证器并完全控制消息的显示方式和时间。
这是我使用的一个:
processMessages(container: FormGroup): { [key: string]: string } {
let messages = {};
for (let controlKey in container.controls) {
if (container.controls.hasOwnProperty(controlKey)) {
let c = container.controls[controlKey];
// If it is a FormGroup, process its child controls.
if (c instanceof FormGroup) {
let childMessages = this.processMessages(c);
Object.assign(messages, childMessages);
} else {
// Only validate if there are validation messages for the control
if (this.validationMessages[controlKey]) {
messages[controlKey] = '';
if ((c.dirty || c.touched) && c.errors) {
Object.keys(c.errors).map(messageKey => {
if (this.validationMessages[controlKey][messageKey]) {
messages[controlKey] += this.validationMessages[controlKey][messageKey] + ' ';
}
});
}
}
}
}
}
return messages;
}
然后,我可以控制添加到messages数组中的内容,从而控制向用户显示的消息。
您可以在此处查看完整代码:https://github.com/DeborahK/Angular2-ReactiveForms在APM文件夹中。
更新
但是现在你已经更新了你的问题以包含一个只有一个输入元素的例子,上面的内容可能有点过分。