Angular2 forms 角度2:如何跨动态创建的组件链接表单元素?

Angular2 forms 角度2:如何跨动态创建的组件链接表单元素?,angular2-forms,angular,Angular2 Forms,Angular,我在动态创建的组件中有一组表单字段。父组件拥有表单标记。但是,没有任何表单字段被添加到表单。我正在使用ComponentFactoryResolver创建组件: @组件({ 选择器:“字段集容器”, templateUrl:'./fieldset container.component.html', 样式URL:['./fieldset container.component.scss'], 入口组件:所有字段集合, }) 导出类FieldsetContainerComponent{ field

我在动态创建的组件中有一组表单字段。父组件拥有
表单
标记。但是,没有任何表单字段被添加到
表单
。我正在使用
ComponentFactoryResolver
创建组件:

@组件({
选择器:“字段集容器”,
templateUrl:'./fieldset container.component.html',
样式URL:['./fieldset container.component.scss'],
入口组件:所有字段集合,
})
导出类FieldsetContainerComponent{
fieldsetComponent:ComponentRef=null;
@Input()formGroup:formGroup;
@ViewChild('fieldSetContainer',{read:ViewContainerRef})
fieldsetContainer:ViewContainerRef;
@Output()onComponentCreation=新的EventEmitter();
构造函数(专用解析器:ComponentFactoryResolver){
}
@Input()集合字段集(字段集:{component:any,resolve:any}){
if(!fieldset)return;//对不起不对
//输入需要采用以下格式才能正确解析
让inputProviders=Object.keys(fieldset.resolve).map((resolveName)=>{return{provide:resolveName,useValue:fieldset.resolve[resolveName]};});
让resolvedInputs=ReflectiveInjector.resolve(inputProviders);
//我们用我们想要传递的数据创建一个注入器,这个注入器的组件
让injector=ReflectiveInjector.fromResolvedProviders(resolvedInputs,this.fieldsetContainer.parentInjector);
//我们用想要创建的组件创建一个工厂
让factory=this.resolver.resolveComponentFactory(findComponentForFieldset(fieldset.component));
//我们使用工厂和喷油器创建部件
let component:ComponentRef=factory.create(喷油器);
//我们将组件插入dom容器中
this.fieldsetContainer.insert(component.hostView);
//销毁以前创建的组件
if(此.fieldsetComponent){
这个.fieldsetComponent.destroy();
}
this.fieldsetComponent=组件;
this.onComponentCreation.emit(this.fieldsetComponent);
}
}
模板:


动态组件的用法:


我怀疑这与喷油器没有正确连接有关,但从我所能知道的情况来看,它是链接到父喷油器的。我在NgModel中设置了一个断点,并为父级传递了一个null,这就是问题所在。我追溯到一些看起来已经编译过的东西,它只是硬编码了一个空值。所以我不确定这是如何用硬编码的空值创建的


关于如何解决这个问题,你有什么想法吗?

好吧,事实证明它与这个组件的动态特性无关。我删除了它并内联定义了所有组件,但它仍然存在问题。问题在于,Angular开箱即用不支持在嵌套在表单标记中的组件中包含表单控件。一旦你在一个组件中嵌套了一个表单控件,它就再也看不到这个表单了,这太疯狂了

在阅读了web上的解决方案并发现没有人有好的解决方案后,我设计了两个自己的指令,将表单注册到NgForm上的DI容器中,然后使用DI层次结构,我可以将其注入另一个指令中,以执行下面的注册

父组件模板:

<form nested>
    <my-component .../>
</form>
<div>
   <input name="street" [(ngModel)]="address.street" required nest/>
   <input name="city" [(ngModel)]="address.city" required nest/>
   <input name="state" [(ngModel)]="address.state" required nest/>
   <input name="zip" [(ngModel)]="address.zip" required nest/>
</div>

子组件模板:

<form nested>
    <my-component .../>
</form>
<div>
   <input name="street" [(ngModel)]="address.street" required nest/>
   <input name="city" [(ngModel)]="address.city" required nest/>
   <input name="state" [(ngModel)]="address.state" required nest/>
   <input name="zip" [(ngModel)]="address.zip" required nest/>
</div>

一旦我有了它,我就可以把我的动态组件带回来,它工作得非常好。真的很难到达那里

它非常优雅和简单,不需要我像网络秀上的许多建议那样通过层传递表单实例。注册表单控件的工作是相同的,无论它是删除1层还是删除999层


IMHO NgForm和NgModel应该直接为我们做这件事,但他们没有,这导致了复杂的体系结构设计来完成中等程度的高级表单。

我认为我们需要工作示例来复制请创建一个plunker。