这只是疯狂,看起来没有办法让一个表单中的一个输入在子组件中.
我已阅读所有博客和教程以及所有内容,无法解决这个问题.
问题是当一个子组件要有任何形式的指令(ngModel,ngModelGroup或其他......)时,它不会工作.
这只是模板驱动表单中的一个问题
这是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;
}
}
Run Code Online (Sandbox Code Playgroud)
yur*_*zui 56
一个简单的解决方案是提供ControlContainer在viewProviders像你的孩子组成的数组:
import { ControlContainer, NgForm } from '@angular/forms';
@Component({
...,
viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]
})
export class ChildComponent {}
Run Code Online (Sandbox Code Playgroud)
另请阅读本文,解释其工作原理.
更新
如果您正在寻找嵌套模型驱动的表单,那么这里是类似的方法:
@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))
}
}
Run Code Online (Sandbox Code Playgroud)
如果你ControlContainer不确切知道自定义组件的包装类型(例如你的控件在FormArray指令中),那么只需使用通用版本:
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 {}
Run Code Online (Sandbox Code Playgroud)
Joh*_*lph 22
通过阅读一堆相关的github问题[1] [2],我还没有找到一种直接的方法来将一个孩子Component的控件添加到父级ngForm(有些人也称它们为嵌套形式,嵌套输入或复杂控件) .
所以我将在这里展示的是一种适用于我的解决方法,ngForm为父母和孩子使用单独的指令.它并不完美,但它让我足够接近我停在那里.
我childFormComponent用一个ngForm指令声明我(即它不是一个html表单标签,只有指令):
<fieldset ngForm="addressFieldsForm" #addressFieldsForm="ngForm">
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" [(ngModel)]="model.email" name="email" #email="ngModel" required placeholder="Email">
</div>
...
Run Code Online (Sandbox Code Playgroud)
然后,Component公开addressFieldsForm作为属性,并将自身导出为模板引用变量:
@Component({
selector: 'mst-address-fields',
templateUrl: './address-fields.component.html',
styleUrls: ['./address-fields.component.scss'],
exportAs: 'mstAddressFields'
})
export class AddressFieldsComponent implements OnInit {
@ViewChild('addressFieldsForm') public form: NgForm;
....
Run Code Online (Sandbox Code Playgroud)
然后,父表单可以使用子表单组件,如下所示:
<form (ngSubmit)="saveAddress()" #ngFormAddress="ngForm" action="#">
<fieldset>
<mst-address-fields [model]="model" #addressFields="mstAddressFields"></mst-address-fields>
<div class="form-group form-buttons">
<button class="btn btn-primary" type="submit" [disabled]="!ngFormAddress.valid || !addressFields.form.valid">Save</button>
</div>
</fieldset>
</form>
Run Code Online (Sandbox Code Playgroud)
请注意,提交按钮显式检查表单ngFormAddress和addressFields表单上的有效状态.这样我至少可以合理地组成复杂的形式,即使它有一些样板.
另一种可行的解决方法
@Directive({
selector: '[provide-parent-form]',
providers: [
{
provide: ControlContainer,
useFactory: function (form: NgForm) {
return form;
},
deps: [NgForm]
}
]
})
export class ProvideParentForm {}
Run Code Online (Sandbox Code Playgroud)
只需将此指令放在节点层次结构顶部的某个子组件中(在任何ngModel之前).
工作原理:NgModel 使用@Host()限定父表单的依赖项查找.因此,父组件中的表单对子组件中的NgModel不可见.但我们可以使用上面演示的代码注入并在子组件中提供它.
| 归档时间: |
|
| 查看次数: |
14892 次 |
| 最近记录: |