2017-06-22 130 views
1

我正在关注这个示例:http://plnkr.co/edit/hQ6RtzCfPosfQl4HlbZQ?p=preview来动态添加和删除表单元素。Angular2 - 嵌套表单元素

html:在这个文件中eventForm.controls.filters给出了一个标识符'filters'没有被定义。 __type不包含此类成员。 FormGroup消息的属性控件,尽管代码有效,并且选择不是独立的。选择一个级别填充所有级别选择。

<table class="example-full-width" cellspacing="0" formArrayname="filters" *ngFor="let filters of eventForm.controls.filters.controls; let i=index"> 
    <span>Address {{i + 1}}</span> 
    <span *ngIf="eventForm.controls.filters.controls.length > 1" (click)="removeFilters(i)">x</span> 
    <tr> 
    <td> 
     <md-select [(ngModel)]="filterUserOcc" [ngModelOptions]="{standalone: true}" placeholder="Occupation" (ngModelChange)="filterUserOccupation()"> 
     <md-option [value]="null">Occupation</md-option> 
     <md-option *ngFor="let occupation of occupations | async" [value]="occupation.occupation"> 
      {{ occupation.occupation }} 
     </md-option> 
     </md-select> 
    </td> 
    </tr> 
    <tr> 
    <td> 
     <md-select [(ngModel)]="filterUserLvl" [ngModelOptions]="{standalone: true}" placeholder="Level" (ngModelChange)="filterUserLevel()"> 
     <md-option [value]="null">Level</md-option> 
     <md-option *ngFor="let level of levels | async" [value]="level.level"> 
      {{ level.level }} 
     </md-option> 
     </md-select> 
    </td> 
    </tr> 
</table> 

app.module.ts

... 
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 
... 


imports: [ 
... 
    ReactiveFormsModule, 
... 
    ], 

component.ts

... 
import { FormGroup, FormControl, FormArray, FormBuilder, Validators } from '@angular/forms'; 
... 

export class NewEventComponent implements OnInit { 

    eventForm: FormGroup; 
... 


    constructor(
... 
    private formBuilder: FormBuilder, 
... 
) { 
... 
    } 

ngOnInit() { 
    this.eventForm = this.formBuilder.group({ 
... 
     filters: this.formBuilder.array([ 
     this.initFilters() 
     ]) 
    }); 

    } 

initFilters() { 
    return this.formBuilder.group({ 
     level: ['', Validators.required], 
     occupation: [''] 
    }); 
    } 

    addFilters() { 
    const control = <FormArray>this.eventForm.controls['filters']; 
    control.push(this.initFilters()); 
    } 

    removeFilters(i: number) { 
    const control = <FormArray>this.eventForm.controls['filters']; 
    control.removeAt(i); 
    } 

回答

1

这是因为你使用双向结合使用,例如用于水平只是一个变量 ,即[(ngModel)]="filterUserLvl",所以当您进行更改时,这意味着您的所有level在表单中具有相同的值。

使用反应形式时,高度不鼓励双向绑定,而是使用表单控件代替ngModel

也注意到你失踪formGroupName为每个表单组的数组内,所以我修改了它..

<div formArrayName="filters"> 
    <table *ngFor="let filters of eventForm.controls.filters.controls; let i=index" 
     [formGroupName]="i"> 
.... 

,然后就删除您模板的ngModelngModelChange和正常工作!

似乎你希望在更改select时触发更改事件,因为您可以传递实际的窗体控件。

DEMO

+1

谢谢。我会尝试一下,看看它是如何工作的。 – Ciprian

+0

*“使用反应形式时,双向绑定是非常不鼓励的,表单控件可以用来代替ngModel。”*的确,我同意你的意见,但直到今天,我还是无法在文档或任何地方找到它。你是否? – developer033

+0

@ developer033我其实是在想从我的答案中编辑出来,但我忘了:P只是注意到使用双向绑定通常会以灾难性结果结束,因为您可能有:D但是您是对的,我不应该我没有证明:P我完全没有发现任何说不应该一起使用的东西。我发现的最接近的东西就是解释为什么ngModel不包含在reactiveforms模块中。 – Alex