我正在尝试创建嵌套表单,但我陷入了第二级,并且不确定addAttribute和removeAttribute将如何显示?
export class ExportFormComponent implements OnInit {
public exportForm: FormGroup;
constructor( private formBuilder: FormBuilder ) { }
ngOnInit() {
this.exportForm = this.formBuilder.group( {
dataType: [''],
items: this.formBuilder.array( [
this.initItem(),
] )
});
}
initItem() {
return this.formBuilder.group( {
exportExpression: [''],
description: [''],
updatable: [true],
attributes: this.formBuilder.array( [
this.initAttribute(),
] )
});
}
initAttribute() {
return this.formBuilder.group( {
exportExpression: [''],
localizedRawField: [''],
localizable: [true],
});
}
addItem() {
const control = <FormArray>this.exportForm.controls['items'];
control.push( this.initItem() );
}
removeItem( i: number ) {
const control = <FormArray>this.exportForm.controls['items'];
control.removeAt( i );
}
addAttribute() {
}
removeAttribute( ) {
}
save( exportConfiguration: ExportConfiguration ) {
console.log( exportConfiguration );
}
}
我的界面树
export interface ExportConfiguration {
dataType?: string,
items?: Item[],
}
export interface Item {
exportExpression?: string,
description?: string,
updatable?: boolean,
attributes?: Attribute[],
}
export interface Attribute {
exportExpression?: string,
localizable?: boolean,
localizedRawField?: string,
rules?: TransformationRule[]
}
export interface TransformationRule {
dataPathKey?: string,
expressionCheck?: boolean,
expression?: string,
}
修改
好的,所以我使用了作为答案之一发布的演示,但我在以下( this.itemsCtrl.get( '${index}.attributes' ) as FormArray )
addAttribute( index: number ) {
( this.itemsCtrl.get( '${index}.attributes' ) as FormArray ).push( this.initAttribute() );
}
答案 0 :(得分:1)
首先,我更喜欢在组件中创建引用来处理控件,而不是一直调用.controls
或.get
。
因此,您的add
和remove
的功能将更加清晰,因为您的模板。
可能是这样的:
exportForm: FormGroup;
dataTypeCtrl: FormControl;
itemsCtrl: FormArray;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
this.dataTypeCtrl = this.formBuilder.control('');
this.itemsCtrl = this.formBuilder.array([this.initItem()]);
this.exportForm = this.formBuilder.group( {
dataType: this.dataTypeCtrl,
items: this.itemsCtrl
});
}
// ...
addItem() {
this.itemsCtrl.push(this.initItem());
}
removeItem(i: number) {
this.itemsCtrl.removeAt(i);
}
addAttribute(index: number) {
this.itemsCtrl.get(`${index}.attributes`).push(this.initAttribute())
}
removeAttribute(itemIndex: number, attrIndex: number) {
this.itemsCtrl.get(`${itemIndex}.attributes`).removeAt(attrIndex)
}
然后,在模板中,您可以直接访问controls
,如下所示:
...
<div formArrayName="items" *ngFor="let itemCtrl of itemsCtrl.controls; let i = index">
<div [formGroupName]="i">
<button (click)="removeItem(i)">Remove item</button>
<input type="text" formControlName="description">
<!-- other inputs from items -->
<button (click)="addAttribute(i)">Add attribute</button>
<div formArrayName="attributes" *ngFor="let attributeCtrl of itemCtrl.get('attributes').controls; let j = index">
<div [formGroupName]="j">
<button (click)="removeAttribute(i, j)">Remove attribute</button>
<input type="text" formControlName="exportExpression"
<!-- other inputs from attributes -->
</div>
</div>
</div>
</div>
参见 DEMO