上下文
Jecelyn Yeen对如何在Angular2中组织嵌套表单有一个excellent article。
在她的例子中,她使用一个数组来显示多个地址表单子组件,这样用户就可以无休止地点击"添加地址"并且表单仍将正确验证。我想做类似的事情,但不是有一个子表单数组,而是根据下拉列表的值显示不同的子表单。
我尝试构造我的代码与她的代码类似,除了不返回表单构建器数组,我为每个要显示的子表单使用表单组。选择下拉选项后,我会删除不应显示的表单组,并重新创建应该显示的表单组。我遇到的问题是,当以这种方式构建时,父表单不会在子表单中获取更改。
守则
TS:
public showNameForm: boolean = false;
public showAddressForm: boolean = false;
public showPhoneNumberForm: boolean = false;
constructor (fb: FormBuilder) {
this.myForm = fb.group({
nameInfo: this.getNameForm(),
addressInfo: this.getAddressForm(),
phoneNumberInfo: this.getPhoneNumberForm()
});
}
getNameForm () {
return this.fb.group({
name: ["", Validators.required]
});
}
getAddressForm () {
return this.fb.group({
address1: ["", Validators.required],
address2: ["", Validators.required],
city: ["", Validators.required],
state: ["", Validators.required],
zipcode: ["", Validators.required]
});
}
getPhoneNumberForm () {
return this.fb.group({
phone: ["", Validators.required]
});
}
handleDropdownSelect (value) {
if(value === 1) {
this.showNameForm = true;
this.myForm.controls['nameInfo'] = this.getNameForm();
delete this.myForm.controls['addressInfo'];
delete this.myForm.controls['phoneNumberInfo'];
}
// Similar for other cases, e.g. if value is 2, only show addressInfo
}
HTML:
<form [formGroup]="myForm">
<div [formGroupName]="'nameInfo'" *ngIf="showNameForm">
<input type="text" formControlName="name" />
</div>
<!-- Similar for other fields -->
<!-- ... -->
<button [ngClass]="{disabled: !myForm.valid}">Submit</button>
</form>
执行此操作后,即使我输入了所有必需的文本,提交按钮也始终无效。使用Chrome调试器检查表单对象,我发现myForm.value
等于
{
nameInfo: {
name: ""
}
}
换句话说,我输入子表单组的文本永远不会被父表单拾取。但是我可以看到myForm.controls.nameInfo
确实具有正确信息的值,并且在选择其他信息时也是如此。所有这些属性的valid
属性都为true
。但是,除非我手动调用myForm.updateValueAndValidity()
,否则父表单不会接收这些更改。这并不理想,因为我希望表单一旦有效就显示为有效,而不必添加我自己的事件监听器来实现它。
答案 0 :(得分:1)
根据评论,问题是隐藏控件,它们仍然计入验证。
如果您隐藏并显示选择FormGroups
并且不希望它们计入验证或form.value
属性,那么您可以在单个控件上调用disable()
或在包含FormGroup
:
this.myForm.addressInfo.disable(); // disables the entire addressInfo group
// which removes it from validation, thus preventing false flags.