我已经使用以下教程在 Angular 2 中创建react式表单,并且效果很好。
https://scotch.io/tutorials/how-to-build-nested-model-driven-forms-in-angular-2
但是,我现在正在尝试在数组中添加一个数组。使用上面的教程,我创建了一个“组织”表单,其中可以包含一组“联系人”组。但是我无法成功调整设置以允许每个“联系人”组包含一组“电子邮件”组。
我一直无法找到涵盖此内容的教程或示例,如果您有任何指点,我将不胜感激。
我已经使用以下教程在 Angular 2 中创建react式表单,并且效果很好。
https://scotch.io/tutorials/how-to-build-nested-model-driven-forms-in-angular-2
但是,我现在正在尝试在数组中添加一个数组。使用上面的教程,我创建了一个“组织”表单,其中可以包含一组“联系人”组。但是我无法成功调整设置以允许每个“联系人”组包含一组“电子邮件”组。
我一直无法找到涵盖此内容的教程或示例,如果您有任何指点,我将不胜感激。
使用上面的教程,我创建了一个“组织”表单,其中可以包含一组“联系人”组。但是我无法成功调整设置以允许每个“联系人”组包含一组“电子邮件”组。
上面的教程为您提供了所需的一切。
我想你想要这样的结构。
首先,您需要一些AppComponent声明 root 的组件(在我的情况下)FormGroup。我在trustForm下面称它。
app.component.ts
export class AppComponent {
trustForm: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit() {
this.trustForm = this.fb.group({
name: '',
contracts: this.fb.array([])
});
this.addContract();
}
initContract() {
return this.fb.group({
name: '',
emails: this.fb.array([])
});
}
addContract() {
const contractArray = <FormArray>this.trustForm.controls['contracts'];
const newContract = this.initContract();
contractArray.push(newContract);
}
removeContract(idx: number) {
const contractsArray = <FormArray>this.trustForm.controls['contracts'];
contractsArray.removeAt(idx);
}
}
在这个组件中,您还有一些方法可以帮助您操作第一级FormArray-contracts
应用程序组件.html
<div class="container">
<form [formGroup]="trustForm">
<h3>Add trust</h3>
<div class="form-group">
<label>Name</label>
<input type="text" class="form-control" formControlName="name">
</div>
<!--contracts-->
<div formArrayName="contracts">
<div *ngFor="let contract of trustForm.controls.contracts.controls; let i=index" class="panel panel-default">
<div class="panel-heading">
<span>Contract {{i + 1}}</span>
<span class="glyphicon glyphicon-remove pull-right" *ngIf="trustForm.controls.contracts.controls.length > 1" (click)="removeContract(i)"></span>
</div>
<div class="panel-body" [formGroupName]="i">
<contract [group]="trustForm.controls.contracts.controls[i]"></contract>
</div>
</div>
</div>
<div class="margin-20">
<button (click)="addContract()" class="btn btn-primary">
Add another contract +
</button>
</div>
</form>
<h5>Details</h5>
<pre>{{ trustForm.value | json }}</pre>
</div>
除了FormArray名称不同之外,与教程中的root html没有区别。
然后你需要构建类似于 AppComponent
合约.component.ts
export class ContractComponent {
@Input('group') contractGroup: FormGroup;
constructor(private fb: FormBuilder) { }
addEmail() {
const emailArray = <FormArray>this.contractGroup.controls['emails'];
const newEmail = this.initEmail();
emailArray.push(newEmail);
}
removeEmail(idx: number) {
const emailArray = <FormArray>this.contractGroup.controls['emails'];
emailArray.removeAt(idx);
}
initEmail() {
return this.fb.group({
text: ''
});
}
}
合同.component.html
<div [formGroup]="contractGroup">
<div class="form-group">
<label>Name</label>
<input type="text" class="form-control" formControlName="name">
</div>
<!--emails-->
<div formArrayName="emails">
<div *ngFor="let email of contractGroup.controls.emails.controls; let i=index" class="panel panel-default">
<div class="panel-heading">
<span>Email {{i + 1}}</span>
<span class="glyphicon glyphicon-remove pull-right" *ngIf="contractGroup.controls.emails.controls.length > 1" (click)="removeEmail(i)"></span>
</div>
<div class="panel-body" [formGroupName]="i">
<email [group]="contractGroup.controls.emails.controls[i]"></email>
</div>
</div>
</div>
<div class="margin-20">
<button (click)="addEmail()" class="btn btn-primary">
Add another email +
</button>
</div>
</div>
正如你所看到的,我们只是替换contracts为emails FormArray,我们也传递FormGroup给电子邮件组件
最后,您只需要填写EmailComponent所需的字段。
email.component.ts
export class EmailComponent {
@Input('group') emailGroup: FormGroup;
}
电子邮件.组件.html
<div [formGroup]="emailGroup">
<div class="form-group">
<label>Text</label>
<input type="text" class="form-control" formControlName="text">
</div>
</div>
您可以在Plunker 示例中找到完整版本
如果你认为,因为父组件拥有像子组件的描述这个解决方案似乎并不正确initContract,并initEmails可以看看更复杂
每个组件负责其功能。
如果您正在寻找模板驱动表单的解决方案,请阅读这篇文章: