我在很多地方的Angular项目中都使用了反应形式,上周我们决定对代码进行一些优化。在检查代码期间,我发现了一个有关以HTML显示表单验证消息的问题。
因此,我已使用以下代码显示验证错误消息:
<form [formGroup]="form">
<div>
<input formControlName="firstName">
<div *ngIf="form.controls.firstName.errors && (form.controls.firstName.touched || form.controls.firstName.dirty)">
This field is required
</div>
</div>
</form>
看起来不错,但是如果我将form.controls.firstName.errors
替换为!form.controls.firstName.valid
会怎样呢?见下文:
<form [formGroup]="form">
<div>
<input formControlName="firstName">
<div *ngIf="!form.controls.firstName.valid && (form.controls.firstName.touched || form.controls.firstName.dirty)">
This field is required
</div>
</div>
</form>
我完全看不出任何区别,但是在我的团队中,有些队友认为我们应该使用!form.controls.firstName.valid
,并且我们在这个小问题上进行了长时间的讨论。我仍然不相信队友。对我来说,如果form
有一个error
,那么它的状态将是invalid
或form
是invalid
,因为它有一个error
。
有人可以建议我应该遵循哪种选择,从根本上说是正确的。
非常感谢。
答案 0 :(得分:2)
如果存在错误,验证器函数将返回错误的对象文字,否则返回null。结果的虚假性是角度知识如何确定控件是否有效。因此,可以假设如果使用.error
或!...valid
,则结果在功能上是等效的。
使用!...valid
(或更合适的.invalid
)说是更明确的方法,如果您看看Angular's examples就是他们的方法。
我这样看:将来谁知道您所依赖的行为是否总是一样?将来可能会有合法的情况,其中错误为null,但控件仍然无效。最好在没有额外成本的情况下采取最明确的方法。
编辑
实际上查看AbstractControl
的来源,可能会导致错误为空,但根据_anyControls()
函数的实现,控件仍然无效:
get invalid(): boolean { return this.status === INVALID; }
/*...*/
private _calculateStatus(): string {
if (this._allControlsDisabled()) return DISABLED;
if (this.errors) return INVALID;
if (this._anyControlsHaveStatus(PENDING)) return PENDING;
/* if the condition below is true that means the control will be invalid
* but errors will be null. */
if (this._anyControlsHaveStatus(INVALID)) return INVALID;
return VALID;
}
鉴于errors
可以为空但控制状态仍为invalid
的条件是可能的,那么您肯定应该检查invalid
而不是errors
。