【发布时间】:2018-02-16 11:32:42
【问题描述】:
我正在尝试将自定义验证器添加到输入,但是当我这样做时会触发 ExpressionChangedAfterItHasBeenCheckedError 错误,说明某些内容从 TRUE 更改为 FALSE。
我将问题追溯到下面一行:
ngOnInit(): void {
this.ipv4Fields.addControl('gateway', new FormControl('', [TabValidator.ipaddress()]));
}
如果我删除 TabValidator.ipaddress(),那么错误就会消失。同样,如果我的验证器强制返回“null”,那么错误就会消失。我的验证器如下:
private static _ipaddress(address: string): any {
console.log('checking ip address: '+address+' valid: '+ip.isV4Format(address)+' is null: '+(address === null ? 'yes' : 'no'));
if (!ip.isV4Format(address)) { return { 'wrongFormat': true }; }
console.log('returning null');
return null;
}
public static ipaddress(): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => {
console.log('validator returning: '+TabValidator._ipaddress(control.value));
return TabValidator._ipaddress(control.value);
};
}
从控制台日志看来,验证器每次都返回相同的值。
有人可以解释这里出了什么问题吗?我无法解释什么变量从“真”变为“假”,因为上面的行中没有涉及布尔值。验证器如何返回不同的值而不出现在我的控制台日志中?
我读过一个关于不在 ngOnInit 中做事的 SO 问题,但这似乎是一个红鲱鱼。
更新:我试过了:
ngOnInit(): void {
Promise.resolve().then(() => {
this.ipv4Fields.addControl('gateway', new FormControl('', [TabValidator.ipaddress()]));
});
}
还有
ngOnInit(): void {
setTimeout(() => this.ipv4Fields.addControl('gateway', new FormControl('', [TabValidator.ipaddress()])), 10);
}
但随后错误变为:
错误错误:找不到名称为“网关”的控件
解决方案:
我将此追溯到一个错误 - 使用响应式表单 + 验证器 + ngb 选项卡。将验证器添加到选项卡上的控件会导致错误。唯一的解决方案是更改为模板表单。
【问题讨论】:
-
这主要发生在组件的渲染顺序不正确时。你生命周期中的某些东西出了问题。关于这个问题的 Angular github 问题页面上有很多线程。检查您的组件。验证您是否没有任何
*ngIf阻止某些组件的渲染等等......我多次遇到这个问题,总是因为我的代码/组件渲染顺序不正确。 -
我没有任何 ngIf 或 ngFor。我确实根据应用于输入的有效性类应用了不同的样式。
-
是的,正如我所说,
*ngIf*可能是一个问题,但有很多事情会导致该错误,正如我所说,主要是因为组件渲染的顺序。代码太少,无法告诉您问题出在哪里。如果您可以在 plunker 中复制(我现在推荐 stackblitz.com)会非常有帮助...
标签: angular validation ngoninit