基于模板的表单中的跨字段验证
问题:是否可以创建某种跨越多个字段但不修改底层模型的验证上下文?如果没有,是否有更好的方法来完成我正在做的事情?
给定这样的模型并假设不可能更改模型:
导出接口(interface) IEvent {
地点?: {
地址:字符串;
城市:字符串;
国家:字符串;
};
onlineUrl?:字符串;
}
构建基于模板的表单(需要填充所有位置对象(地址、城市、国家/地区)或填充 onlineUrl)的最佳方法是什么?
Here is a working Plunk我可以进行自定义验证,但存在一些挑战:
- 为了匹配模型,我们需要在位置字段周围有一个 ngModelGroup,但 onlineUrl 不应该位于该 ngModelGroup 内,因为它不是位置对象的一部分。由于 onlineUrl 不在 ngModelGroup 内部,因此很难提出一致的验证方法。请注意,在此示例中,我们在 ngModelGroup 上添加了一个自定义验证器,这似乎打破了一些基本验证前提 - 例如,请注意,当字段无效时,红色突出显示仅显示在位置字段旁边,因为自定义验证器位于 ngModelGroup 上,而 onlineUrl 不在该组内。
- 在 onlineUrl 字段中输入不会自动触发重新验证,因为该字段不在具有自定义验证器的 ngModelGroup 中。为了完成这项工作,我需要添加此绑定(bind):
(change)="locationGroup.control.controls.address.updateValueAndValidity()"
到 onlineUrl 字段,以便触发字段验证在 ngModelGroup 内部。这看起来并不理想。
重申问题:是否可以创建某种跨越多个字段但不修改底层模型的验证上下文?
最佳答案
您可以将“validateLocation”指令放在顶部“form”标记中:
<form #myForm="ngForm" (ngSubmit)="save(myForm)" autocomplete="off" novalidate validateLocation>
<fieldset ngModelGroup="location">
然后 validate() 方法通过“FormGroup.value”获取位置和 onlineUrl 的访问权限,如下所示:
if (control && control.value && control.value.location) {
let g = control.value;
if (g.location.address && g.location.city && g.location.country)
return null;
if (g.onlineUrl)
return null;
}
return {validateLocation: false}
尝试this plunker 。当捕获位置或 url 时,Form.valid 将变为 true。
关于forms - 如何在 Angular 2 中使用复杂模型添加跨领域验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39455666/