2017-02-23 115 views
1

我想創建嵌套表單,但我卡在第二級,不知道addAttribute和removeAttribute將如何看起來像?Angular2創建模型嵌套表格

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

你能描述最終表單的控件樹的形狀,指示哪些部分是動態的? – AngularChef

+0

@AngularFrance:我更新了。它有幫助 –

回答

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

+0

謝謝。這是什麼意思this.formBuilder.control('') –

+0

@SaurabhKumar不客氣:)'this.formBuilder.control('')'是新的FormControl('')的糖(或不) 。我編輯了包含演示的答案,您可以在那裏查看所有* source *。 – developer033

+0

哦,這是超級酷。真棒。非常感謝我學習角度:) –