我们说我们有一个地址,并希望以多种形式重复使用它(例如,人,公司......) 在Angular中,一切都是组件,所以我们应该编写一个组件。
最好的方法是什么?事实证明,这并不容易。它应该封装数据并验证嵌入的表单字段。我找到了两个问题的解决方案:
1。自定义表单组件
我不喜欢它:过于复杂,在子组件内部的一切都是委派。 通过验证,您将需要某种内部形式"验证工作。表单控件必须在父级中定义,封装实际上是不可能的。 简单的例子,见: https://stackblitz.com/edit/angular-nested-form-custum-component-test
2。组件,有两个输入:FormGroup和form-submitted-state
来自https://medium.com/spektrakel-blog/angular2-building-nested-reactive-forms-7978ecd145e4
的想法比自定义表单组件简单得多。我们需要提供在嵌套组件外部构建的FormGroup。 如果我们想要显示验证错误" onSubmit",我们还需要提供表单提交状态'到儿童组件。 简单的例子,见 https://stackblitz.com/edit/angular-nested-formcomponent-test
任何评论或更好的想法来解决问题?
答案 0 :(得分:1)
您可以通过将FormGroup传递给具有初始值的嵌套控件来支持封装,并允许嵌套控件定义自己的内部表单组以及任何验证器。
<强> app.component.html 强>
<nested-form-cmp
init="foo"
[formSubmitted]="f.submitted"
[grp]="myForm">
</nested-form-cmp>
AppComponent只需要初始化自己的表单数据:
export class AppComponent {
myForm: FormGroup;
constructor(private fb: FormBuilder) {
this.myForm = fb.group({
name: ['', Validators.required]
})
}
submit(form: NgForm) {
console.log("Reactive Form submitted: " + form.submitted);
}
}
<强>嵌套form.component.html 强>
嵌套组件将负责创建自己的嵌套FormGroup,并使用验证器初始化它:
<div [formGroup]="grp">
<div formGroupName="innerGrp">
<label>
Inner name:
<input formControlName="name2" type="text" id="outer"/>
</label>
<span class="error" *ngIf="(formSubmitted || grp.get('innerGrp.name2').touched) && grp.get('innerGrp.name2').hasError('required')">
Inner name is required
</span>
</div>
</div>
<强>嵌套form.component.ts 强>
export class NestedFormComponent implements OnInit{
// The FormGroup built in the parent
@Input() public grp: FormGroup;
@Input() public init: string;
// Needed, because the FormGroup does not get the forms submitted state
@Input() public formSubmitted: boolean;
constructor(private fb: FormBuilder){
}
ngOnInit() {
this.grp.setControl('innerGrp', this.fb.group({
name2: [this.init, Validators.required]
}))
}
}