假设我有一些带有一些字段的简单形式(Stackblitz example):
@Component({
selector: 'my-app',
template:
`
<h1>AppComponent</h1>
<form>
<h2>UserData</h2>
<userdata [user]="model.userData"></userdata>
<h2>Actions</h2>
<actionbar ></actionbar>
</form>
`,
})
export class AppComponent { ... }
@Component({
selector: 'userdata',
template:
`
<span class="status {{name.status}}">{{name.status}}</span>
full name:
<input name="name" #name="ngModel" pattern="^.* .*$" required [(ngModel)]="user.name">
<br>
<h3>--- Contacts ---</h3>
<span class="status {{email.status}}">{{email.status}}</span>
email:
<input name="email" #email="ngModel" type="email" [email]="true" [(ngModel)]="user.contacts.email">
<br>
<span class="status {{phone.status}}">{{phone.status}}</span>
phone:
<input name="phone" #phone="ngModel" pattern="^[0-9]*$" [(ngModel)]="user.contacts.phone">
<br>
<h4>---- Address ----</h4>
<span class="status {{street.status}}">{{street.status}}</span>
street:
<input name="street" #street="ngModel" [(ngModel)]="user.contacts.address.street">
<br>
<span class="status {{city.status}}">{{city.status}}</span>
city:
<input name="city" #city="ngModel" [(ngModel)]="user.contacts.address.city">
<br>
<span class="status {{zipcode.status}}">{{zipcode.status}}</span>
zipcode:
<input name="zipcode" #zipcode="ngModel" pattern="^[0-9]{5}$" [(ngModel)]="user.contacts.address.zipcode">
<br>
`,
viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],
})
export class UserDataComponent {
@Input() user: any;
}
@Component({
selector: 'actionbar',
template:
`
<span class="status {{form.status}}">{{form.status}}</span>
<input type="button" value="Submit" [disabled]="form.invalid">
`,
viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],
})
export class ActionBarComponent { ... }
(基本上是一个包含全名和联系信息字段的表单,如电子邮件,电话,地址)
请注意,如果表单有效,则只能提交表单 . 只有嵌套在其中的所有内容都有效时,该表单才有效 .
对于单个字段的验证,它很容易做(这些字段已经有一些,如正则表达式模式和要求) .
现在我想添加另外两个业务需求:
-
至少需要一个联系信息(电子邮件,电话或地址);
-
如果设置了地址中的任何字段,则需要所有字段(街道,城市,邮政编码) .
Is it possible to even do it in template-driven forms?
2 回答
这就是我如何设法实现组验证(Stackblitz Example) .
(对于我在下面粘贴的片段,括号中的省略号表示为了清晰起见省略了部分;请参阅上面的stackblitz示例获取完整内容)
对于每个组,我添加了一个包装元素(我认为它也可能是
<ng-container>
,虽然没有测试它)只是为了承载ngModelGroup
指令:现在,每个新的
ngModelGroup
都可以附加验证器 . 由于这些验证是如此临时,我觉得它们不值得一个真正可重用的实现,我只需要验证函数(在这里粘贴其中一个;另一个非常直接,你总是可以参考stackblitz ):(此代码在
UserDataComponent
内实现)现在要使角形式引擎调用我的函数,我必须实现
Validator
,但是通用的(将验证交给函数):要使用它(并绑定我的验证函数),我必须将组的元素更改为:
而且,作为一个整体的小组得到了我的临时功能的验证 .
这是可能的,但由于代码变得模糊不清,因此它是不切实际的 .
条件1:
并且对于每个输入,必须满足不同的条件 . 如果没有输入任何输入,则需要输入 .
条件2:
这里只是相反 - 没有否定
如果提供的字段之一不为空,则需要输入 .
使用反应形式这样做会容易得多 . 条件将大致相同,但更容易阅读,维护和更改 .