Angular2 嵌套模板驱动表单
[英] Angular2 nested template driven form
本文介绍了Angular2 嵌套模板驱动表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
这简直是疯了,看起来没有办法让表单的其中一个输入位于子组件中.
我已经阅读了所有的博客和教程以及所有内容,但没有办法解决这个问题.
问题是当子组件将有任何类型的表单指令(ngModel、ngModelGroup 或其他任何……)时,它就无法工作.
这只是模板驱动表单的问题
这是plunker:
import { Component } from '@angular/core';@成分({选择器:'子表单组件',模板:`<fieldset ngModelGroup="地址"><div><label>街道:</label><input type="text" name="street" ngModel>
<div><label>邮编:</label><input type="text" name="zip" ngModel>
<div><label>城市:</label><input type="text" name="city" ngModel>
</fieldset>`})导出类 childFormComponent{}@成分({选择器:'表单组件',指令:[childFormComponent],模板:`<form #form="ngForm" (ngSubmit)="submit(form.value)"><fieldset ngModelGroup="name"><div><label>名字:</label><input type="text" name="firstname" ngModel>
<div><label>姓氏:</label><input type="text" name="lastname" ngModel>
</fieldset><child-form-component></child-form-component><button type="submit">提交</button></表单><预>{{form.value |json}}
<h4>已提交</h4><预>{{值|json }}
`})导出类 FormComponent {价值:任何;提交表格) {this.value = 形式;}}
解决方案
一个简单的解决方案是在您的子组件的 viewProviders
数组中提供 ControlContainer
,例如:
import { ControlContainer, NgForm } from '@angular/forms';@成分({...,viewProviders: [ { 提供: ControlContainer, useExisting: NgForm } ]})导出类 ChildComponent {}
Stackblitz 示例
另请阅读这篇文章,解释其工作原理.
更新
如果您正在寻找嵌套模型驱动形式,那么这里是类似的方法:
@Component({选择器:'my-form-child',模板:`<input formControlName="age">`,视图提供者:[{提供:ControlContainer,useExisting: FormGroupDirective}]})导出类 ChildComponent {构造函数(私有父级:FormGroupDirective){}ngOnInit() {this.parent.form.addControl('age', new FormControl('', Validators.required))}}
Ng-run 示例
更新 2
如果您不确切知道哪种类型的 ControlContainer
包装了您的自定义组件(例如您的控件在 FormArray 指令中),那么只需使用通用版本:
import { SkipSelf } from '@angular/core';从@angular/forms"导入{ ControlContainer};@成分({...,视图提供者:[{提供:ControlContainer,useFactory: (容器: ControlContainer) =>容器,deps: [[new SkipSelf(), ControlContainer]],}]})导出类 ChildComponent {}
Ng-run 示例
This is just madness , looks like there is no way to have a form which one of it's inputs is in a child component .
I have read all the blogs and tutorials and everything , no way to work this out .
The problem is when a child component is going to have any kind of form directives ( ngModel , ngModelGroup or whatever ..) , it wont work.
This is only a problem in template driven forms
This is the 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;
}
}
解决方案
One simple solution is to provide ControlContainer
in viewProviders
array of your child component like:
import { ControlContainer, NgForm } from '@angular/forms';
@Component({
...,
viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]
})
export class ChildComponent {}
Stackblitz Example
Read also this article that explains why it's working.
Update
If you're looking for nested model driven form then here is the similar approach:
@Component({
selector: 'my-form-child',
template: `<input formControlName="age">`,
viewProviders: [
{
provide: ControlContainer,
useExisting: FormGroupDirective
}
]
})
export class ChildComponent {
constructor(private parent: FormGroupDirective) {}
ngOnInit() {
this.parent.form.addControl('age', new FormControl('', Validators.required))
}
}
Ng-run Example
Update 2
If you don't know exactly which type of ControlContainer
wraps your custom component(for example your controls is inside FormArray directive) then just use common version:
import { SkipSelf } from '@angular/core';
import { ControlContainer} from '@angular/forms';
@Component({
...,
viewProviders: [{
provide: ControlContainer,
useFactory: (container: ControlContainer) => container,
deps: [[new SkipSelf(), ControlContainer]],
}]
})
export class ChildComponent {}
Ng-run Example
这篇关于Angular2 嵌套模板驱动表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!