2016-07-29 91 views
7

我想创建一个表单组件,其中组件提供<form>及其后代的表单内容,即控件。我正在使用反应形式的RC4。该组件应该使用这样的:角度2表单遍布组件

<my-formwizard [form]="form"> 
    <input formControlName="name" type="text" /> 
</my-formwizard> 

这里是展示实施普拉克:http://plnkr.co/edit/OSzjDQD63lwoEsyqdLvw?p=preview

我碰到一个例外:类型错误:无法读取空的特性“的setParent”

是否有实现跨多个组件的反应式表单传播的方式?


UPDATE:RC5有更清晰的错误消息,并感谢peeskillet的输入,formControlName可如果自定义指令获取连接通过formGroup属性FormGroup使用。更新后的普拉克显示了跨两个组件的工作传播形式:

http://plnkr.co/edit/1VfIH5AYjoe7dmizw6ss?p=preview

+0

你的解决方案是真多一个黑客,并导致_two_'FormGroupDirective'要创建的实例,这是不是你想。 –

回答

6

在你Plunker,我不知道为什么你的ngForm

<my-formwizard [form]="form" ngForm="form"> 

但是这不应该存在。我认为它甚至可能会创造出一种全新的形式。应该删除。一旦你删除,那么你会遇到另一个问题,说没有ControlContainerControlContainerFormGroupDirective[formGroup])。

问题是由formControlName造成的。如果您查看FormControlName directive的源代码,并查看构造函数,则会看到它需要ControlContainer依赖项。但不仅如此,它还有一个装饰器,这意味着它只会在主机注入器中查找ControlContainer

老实说,在这种情况下,我并不十分确定在这种情况下哪个喷油器用作主喷油器,但它看起来并不是带有组指令的喷油器。也许是因为你如何设置组件。

一个解决方案,我发现它而不是使用formControlName,而是使用[formControl],而只是通过一个FormControl实例。 FormControlDirective没有这个问题(它需要一个ControlContainer),因为它可以独立使用。

所以,你可以做到这一点,而不是

<input [formControl]="nameCtrl" type="text" /> 

export class App { 

    form: FormGroup; 
    nameCtrl: FormControl; 

    constructor(fb: FormBuilder) { 
    this.nameCtrl = new FormControl(''); 
    this.form = fb.group({ 
     name: this.nameCtrl 
    }); 
    } 
} 

这可以解决你的问题。下面是更新Plunker

另请参见:


1 - 有一个良好的读取见Host and Visibility...在这个题目

+0

感谢您的解决方法。我发现创建单个控件并为每个控件保留一个属性是相当乏味的,这就是为什么我正在寻找一个formControlName解决方案。我刚刚尝试了'forms-builds'中的当前代码,它显示了相同的行为,只是一个更详细的错误消息:“formControlName必须与父formGroup指令一起使用,您需要添加formGroup指令并将其传递给现有FormGroup实例(您可以在您的课堂上创建一个实例)“。如果我将“formGroup”添加到我的指令,它似乎工作! – achimha

+0

因为那么'formGroup'指令是'fromControlName'的直接主机,当它执行主机查找时,允许'ControlContainer'被'FormControlName'发现。 –