如何在Angular 2中添加复杂模型的跨场验证

时间:2016-09-12 17:28:56

标签: forms validation angular

基于模板的表单中的跨字段验证

问题 :是否可以创建某种跨越多个字段但不修改基础模型的验证上下文?如果没有,是否有更好的方法来做我正在做的事情?

给定这样的模型,假设无法更改模型

export interface IEvent { location?: { address: string; city: string; country: string; }; onlineUrl?: string; }

构建基于模板的表单的最佳方法是什么,该表单需要填充所有位置对象(地址,城市,国家/地区)或要填充onlineUrl?

Here is a working Plunk我在哪里进行自定义验证,但存在一些挑战:

  1. 为了匹配模型,我们需要围绕位置字段的ngModelGroup,但是onlineUrl不应该在该ngModelGroup内,因为它不是位置对象的一部分。由于onlineUrl不在ngModelGroup中,因此很难提出一种有凝聚力的验证方法。请注意,在此示例中,我们在ngModelGroup上添加了一个自定义验证器,它似乎打破了一些基本的验证前提 - 例如,请注意,当字段无效时,红色突出显示仅显示在位置字段旁边,因为自定义验证器位于ngModelGroup上,onlineUrl不在该组内。
  2. 键入onlineUrl字段不会自动触发重新验证,因为此字段不在其上具有自定义验证器的ngModelGroup中。为了完成这项工作,我需要将此绑定:(change)="locationGroup.control.controls.address.updateValueAndValidity()"添加到onlineUrl字段,以便在ngModelGroup内的字段上触发验证。这似乎并不理想。
  3. 重述问题 :是否可以创建某种跨越多个字段但不修改基础模型的验证上下文?

1 个答案:

答案 0 :(得分:2)

您可以将'validateLocation'指令放在顶部'form'标记中:

<form #myForm="ngForm" (ngSubmit)="save(myForm)" autocomplete="off" novalidate validateLocation>

  <fieldset ngModelGroup="location">

然后,validate()方法通过'FormGroup.value'访问location和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。当捕获位置或网址时,Form.valid将变为true。