2016-08-30 29 views
9

我工作的一個模型驅動的形式,我不能讓它將項目添加到正在顯示與ngFor列表。當我嘗試迭代我的列表時,我目前收到錯誤消息。如何使用數組遍歷formgroup在Angular2

錯誤:

Error: Cannot find control with path: 'locations -> i' 
    at new BaseException (exceptions.ts:21) 
    at _throwError (shared.ts:80) 
    at Object.setUpFormContainer (shared.ts:66) 
    at FormGroupDirective.addFormGroup (form_group_directive.ts:74) 
    at FormGroupName.AbstractFormGroupDirective.ngOnInit (abstract_form_group_directive.ts:37) 
    at DebugAppView._View_PersonFormComponent4.detectChangesInternal (PersonFormComponent.ngfactory.js:3197) 
    at DebugAppView.AppView.detectChanges (view.ts:260) 
    at DebugAppView.detectChanges (view.ts:378) 
    at DebugAppView.AppView.detectContentChildrenChanges (view.ts:279) 
    at DebugAppView._View_PersonFormComponent2.detectChangesInternal (PersonFormComponent.ngfactory.js:1995) 
Raw person-form-builder.service.ts 

formBuilderService:

import {Injectable} from "@angular/core"; 
import {Validators, FormBuilder} from '@angular/forms'; 

import {Person} from './../components/person/person'; 

@Injectable() 

export class PersonFormBuilderService { 

    constructor(private fb: FormBuilder) { 
    } 

    getForm(person: Person) { 
     return this.fb.group({ 
      _id: [person._id], 
      name: this.fb.group({ 
       first: [person.name.first], 
       middle: [person.name.middle], 
       last: [person.name.last], 
       full: [person.name.full], 
      }), 
      locations: this.fb.array([ 
       this.initLocation(), 
      ]), 
      files: this.fb.array([ 
       this.initFiles(), 
      ]), 
      skills: this.fb.array([ 
       this.initSkills(), 
      ]), 
     }); 
    } 

    initLocation() { 
     return this.fb.group({ 
      isDefault: [false, Validators.required], 
      location: ['', Validators.required], 
      roles: ['', Validators.required], 
      isContact: [false, Validators.required], 
      contactPhone: ['', Validators.required], 
      contactPhoneExt: ['', Validators.required], 
     }); 
    } 

    initFiles() { 
     return this.fb.group({ 
      originalName: ['', Validators.required], 
     }); 
    } 

    initSkills() { 
     return this.fb.group({ 
      name: ['', Validators.required], 
      isrequired: [false, Validators.required], 
      expireDate: ['', Validators.required], 
      canOverride: [false, Validators.required], 
     }); 
    } 

    addLocation(control) { 
     control.push(this.initLocation()); 
    } 

    removeLocation(i: number, control) { 
     control.removeAt(i); 
    } 
} 

形式:

<div formGroup="form"> 
    <div formArrayName="locations"> 
     <div *ngFor="let location of form.controls.locations.controls; let i=index"> 
      <span>Location {{i + 1}}</span> 
      <div formGroupName="i"> 
       <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect"> 
        <input type="checkbox" class="mdl-checkbox__input" 
         formControlName="isDefault" [checked]=""> 
       </label> 
      </div> 
     </div> 
    </div> 
</div> 

形狀component.ts:

import {Component} from '@angular/core'; 
import {FormGroup, FormArray} from '@angular/forms'; 

@Component({ 
    moduleId: module.id, 
    selector: 'person-form-component', 
    templateUrl: 'person-form.component.html', 
    providers: [PersonService, PersonFormBuilderService] 
}) 

export class PersonFormComponent { 
    getPerson(personId) { 
     this.personService.getPerson(this.personId).subscribe(res => { 
      this.person = res.data; 
      this.form = this.personFormBuilderService.getForm(this.person); 
     }); 
    } 

    addLocation() { 
     let control = <FormArray> this.form.controls['locations']; 
     this.personFormBuilderService.addLocation(control); 
    } 
} 

https://gist.github.com/jpstokes/11551ff5d8c76514005c6c9fd8a554dd

+0

看一看[這](https://www.youtube.com/watch?v = E92KS_YCSf8)。卡拉埃裏克森正在展示一種方式來做到這一點。從30分鐘開始。 – Tom

回答

9

固定它!

因此很明顯,我需要在Angular2基礎閱讀,因爲我覺得我的錯誤是合法的。基本上,我忽略了本教程中formGroupName的方括號,因爲在無問題之前我已經做了很多次,但現在還沒有。所以要解決我只是添加括號:

<div formGroupName="i"> => <div [formGroupName]="i"> 
7

這是爲我工作的解決方案。 https://plnkr.co/edit/cs244r

HTML模板:

<div> 
     <h2>RegionId: {{regionId}}</h2> 
     <h2>Region: {{region.name}}</h2> 
    </div> 
    <form [formGroup]="regionFormGroup"> 
     Region Name: <input type="text" formControlName="regionName" [(ngModel)]="region.name" /> 
     <div formArrayName="customersArray"> 
     <table class="simple-table"> 
     <tr> 
      <th>Customer</th> 
      <th>Current Period</th> 
      <th>Previous Period</th> 
     </tr> 
     <tbody> 
      <tr [formGroupName]="i" *ngFor="let customerGroup of regionFormGroup.controls.customersArray.controls; let i = index"> 
      <td>{{region.customers[i].name}} - index {{i}}</td> 
      <td><input type="text" formControlName="currentPeriod" [(ngModel)]="region.customers[i].currentPeriod"/></td> 
      <td><input type="text" formControlName="previousPeriod" [(ngModel)]="region.customers[i].previousPeriod"></td> 
      </tr> 
     </tbody> 
     </table> 
     </div> <!-- end: div FormArrayName --> 
    </form> 

Component.ts

export class AppComponent implements OnInit { 

    regionId: number = 5; 
    region: RegionModel; 
    regionFormGroup: FormGroup; 

    constructor(private customerService: CustomerService,private fb: FormBuilder) { } 

    ngOnInit(): void { 

    // initialize form 
    this.regionFormGroup = new FormGroup({ 
     regionName: new FormControl(''), 
     customersArray: new FormArray([]) 
    }); 

    // Retrieve data from datasource 
    this.customerService.getCustomerByRegion(5) 
     .subscribe((reg: RegionModel) => { 
     this.region = reg; 
     this.buildForm(); 
     }); 
    } 

    buildForm =() : void => { 

    const customersControls = <FormArray>this.regionFormGroup.controls['customersArray']; 

    this.region.customers.forEach((cust : CustomerModel) => { 
     customersControls.push(this.createCustomerFormGroup(cust)); 
     console.log(customersControls); 
    }); 
    } 

    createCustomerFormGroup(cust: CustomerModel) { 

     return this.fb.group({ 
      currentPeriod: [''], 
      previousPeriod: [''] 
     }); 
    } 
} 
+2

這確實有幫助。投票。 –

+0

這對我也有幫助。謝謝! – Ivan

+0

它會給問題在aot –