这只是疯狂,看起来没有办法让一个表单中的一个输入在子组件中 .
我已阅读所有博客和教程以及所有内容,无法解决这个问题 .
问题是当子组件将具有任何类型的表单指令(ngModel,ngModelGroup或其他......)时,它将无法工作 .
This is only a problem in template driven forms
这是plunker:
import { Component } from '@angular/core';
@Component({
selector: 'child-form-component',
template: `
<fieldset ngModelGroup="address">
<div>
<label>Street:</label>
<input type="text" name="street" ngModel>
</div>
<div>
<label>Zip:</label>
<input type="text" name="zip" ngModel>
</div>
<div>
<label>City:</label>
<input type="text" name="city" ngModel>
</div>
</fieldset>`
})
export class childFormComponent{
}
@Component({
selector: 'form-component',
directives:[childFormComponent],
template: `
<form #form="ngForm" (ngSubmit)="submit(form.value)">
<fieldset ngModelGroup="name">
<div>
<label>Firstname:</label>
<input type="text" name="firstname" ngModel>
</div>
<div>
<label>Lastname:</label>
<input type="text" name="lastname" ngModel>
</div>
</fieldset>
<child-form-component></child-form-component>
<button type="submit">Submit</button>
</form>
<pre>
{{form.value | json}}
</pre>
<h4>Submitted</h4>
<pre>
{{value | json }}
</pre>
`
})
export class FormComponent {
value: any;
submit(form) {
this.value = form;
}
}
5 回答
一个简单的解决方案是在子组件的
viewProviders
数组中提供ControlContainer
,如:Stackblitz Example
另请阅读本文,解释其工作原理 .
Update
如果您正在寻找 nested model driven form ,那么这里是类似的方法:
Ng-run Example
更新2
如果您不确切知道哪种类型的
ControlContainer
包装了您的自定义组件(例如您的控件在FormArray指令中),那么只需使用通用版本:Ng-run Example
通过阅读一堆相关的github问题[1] [2],我还没有找到一种直接的方法来将一个子项
Component
的控件添加到父级ngForm
(有些人还称它们为嵌套表单,嵌套输入或复杂控件) .所以我将在这里展示的是一个适合我的解决方法,为父母和孩子使用单独的
ngForm
指令 . 这不是完美的,但它让我足够接近,我停在那里 .我用
ngForm
指令声明我的childFormComponent
(即它是 not 一个html表单标签,只有指令):然后,组件将
addressFieldsForm
作为属性公开,并将自身导出为template reference variable:然后,父表单可以使用子表单组件,如下所示:
请注意,提交按钮显式检查
ngFormAddress
和addressFields
表单上的有效状态 . 这样我至少可以合理地组成复杂的形式,即使它有一些样板 .另一种可行的解决方法
只需将此指令放在节点层次结构顶部的某个子组件中(在任何ngModel之前) .
How it works :NgModel qualifies父表单与@Host()的依赖关系查找 . 因此,父组件中的表单对子组件中的NgModel不可见 . 但是我们可以使用上面演示的代码注入并在子组件中提供它 .
来自官方docs:
This directive can only be used as a child of NgForm.
所以我认为你可以尝试将你的子组件包装在不同的
ngForm
中,并期望子组件的父组件结果@Output
. 如果您需要更多说明,请与我们联系 .UPDATE: 这是Plunker有一些更改,我将子表单转换为模型驱动,因为在提交之前无法在表单驱动表单上进行更新以进行更新 .
我've created a solution using a directive and service. Once you add those to your module, the only other code change you need to make are at the form level in the templates. This works with dynamically added form fields and AOT. It also supports multiple unrelated forms on a page. Here'是吸虫:plunker .
它使用此指令:
而这项服务:
要在父组件中使用带有表单的指令:
然后在子组件中: