我有一个注册表单,用户可以在其中向新的或现有的组织添加一个/多个地址、一个/多个电话,地址和电话实际上是(可重用的)组件。
例如,Phone 组件与 Android 联系人详细信息组件类似,它有 3 个 FormControls:一个 Type(下拉列表)、一个数字(输入)和一个删除按钮。
最后,必须提交整个表单以保存信息。
问题:如何动态添加电话到表单并显示已经存在的电话? (下面的代码和标记)。非常感谢您花时间和精力回答我!
organization-detail.component.ts
import { Component, Input } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, FormControl, Validators } from '@angular/forms';
import { Organization } from './organization';
import { PhoneDetailComponent } from "../phone-detail/phone-detail.component";
@Component({
selector: 'organization-detail',
templateUrl: './organization-detail.component.html',
styleUrls: ['./organization-detail.component.css']
})
export class OrganizationDetailComponent {
organizationForm: FormGroup;
constructor (private fb: FormBuilder){
this.createForm();
}
createForm() {
this.organizationForm = this.fb.group({
accountingId: [''],
externalId: '',
isHost: false,
logoPath: '',
name: ['',
[Validators.required,
Validators.minLength(4),
Validators.maxLength(24)]
], // <--- the FormControl called "name"
notes: '',
registrationNo: '',
vATId: '',
webSite: '',
phones: new FormArray([])
//phones: new Array<PhoneDetailComponent>
});
}
onSubmit() {
console.log(this.organizationForm);
}
onAddPhone() {
const control = new PhoneDetailComponent();
(<FormArray>this.organizationForm.get('phones')).push(control);
}
}
organization-detail.component.html
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
<h2>Organization Detail</h2>
<form [formGroup]="organizationForm" (ngSubmit)="onSubmit()" class="form-horizontal">
<div class="form-group">
<label for="isHost"> Is host:</label>
<input type="checkbox" id="isHost" formControlName="isHost" class="check" />
</div>
<div class="form-group">
<label for="name">Name:</label>
<input type="text" id="name" class="form-control" formControlName="name" placeholder="Organization name" />
<span
*ngIf="!organizationForm.get('name').valid && organizationForm.get('name').touched"
class="help-block">Please enter a valid name!</span>
</div>
<div class="form-group">
<label for="accountingId">Accounting Id:</label>
<input type="text" id="accountingId" class="form-control" formControlName="accountingId" />
</div>
<div class="form-group">
<label for="externalId">External Id:</label>
<input type="text" id="externalId" class="form-control" formControlName="externalId" />
</div>
<div class="form-group">
<label for="registrationNo">Registration No:</label>
<input type="text" id="registrationNo" class="form-control" formControlName="registrationNo" />
</div>
<div class="form-group">
<label for="vATId">VAT Id:</label>
<input type="text" id="vATId" class="form-control" formControlName="vATId" />
</div>
<div class="form-group">
<label for="webSite">Web site:</label>
<input type="text" id="webSite" class="form-control" formControlName="webSite" />
</div>
<div class="form-group">
<label for="logoPath">Logo path:</label>
<input type="text" id="logoPath" class="form-control" formControlName="logoPath" />
</div>
<div class="form-group">
<label for="notes">Notes:</label>
<textarea id="notes" class="form-control" formControlName="notes" rows="3"></textarea>
</div>
<div formArrayName="phones">
<h4>Phones:</h4>
<button class="btn btn-default" type="button"
(click)="onAddPhone()">
Add phone
</button>
<div class="form-group"
*ngFor="let phoneControl of organizationForm.get('phones').controls; let i = index">
<!--<input type="text" class="form-control" [formControlName]="i">-->
<phone-detail></phone-detail>
</div>
</div>
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Go!</button>
</span>
</div>
</div>
<button class="btn btn-primary" type="submit">Submit</button>
</form>
</div>
</div>
</div>
<p>Form value: {{ organizationForm.value | json }}</p>
<p>Form status: {{ organizationForm.status | json }}</p>
phone-detail.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { Phone } from "./phone";
@Component({
selector: 'phone-detail',
templateUrl: './phone-detail.component.html',
styleUrls: ['./phone-detail.component.css']
})
export class PhoneDetailComponent implements OnInit {
@Input('phoneItem') item: Phone;
constructor() { }
ngOnInit() {
}
}
phone-detail.component.html
<div class="container">
<div class="row">
<div class="col-xs-3">
<select class="form-control">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</div>
<div class="col-xs-7">
<input type="text" class="form-control">
</div>
<div class="col-xs-2">
<button class="btn">X</button>
</div>
</div>
</div>
最佳答案
在你的父级中,有格式数组:
phones: this.fb.array([])
然后在父模板中将这个 formarray 中的每个表单组传递给子模板:
<button (click)="addPhone()">Add phone</button>
<div formArrayName="phones">
<div *ngFor="let ctrl of organizationForm.controls.phones.controls; let i=index">
<button (click)="removePhone(i)">X</button>
<phone-detail [group]="ctrl"></phone-detail>
</div>
</div>
在 child 中使用@Input
:
@Input() group: FormGroup;
并在模板中添加表单控件和表单组:
<div [formGroup]="group">
<select formControlName="type">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
<input type="text" formControlName="num">
</div>
最后是删除和添加放置在父级中的表单组:
initPhone() {
return this.fb.group({
type: [''],
num: ['']
});
}
addPhone() {
const control = this.organizationForm.controls.phones;
control.push(this.initPhone());
}
removePhone(i: number) {
const control = this.organizationForm.controls.phones;
control.removeAt(i);
}
This article 关于这个问题值得一读!
关于angular - 将组件动态添加到表单中的 FormArray( Angular 2/4),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44471532/