Angular2创建模型嵌套表单

时间:2017-02-23 13:52:33

标签: angular angular2-forms

我正在尝试创建嵌套表单,但我陷入了第二级,并且不确定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 )

中得到null
addAttribute( index: number ) {
        ( this.itemsCtrl.get( '${index}.attributes' ) as FormArray ).push( this.initAttribute() );
    }

1 个答案:

答案 0 :(得分:1)

首先,我更喜欢在组件中创建引用来处理控件,而不是一直调用.controls.get

因此,您的addremove功能将更加清晰,因为您的模板

可能是这样的:

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