web-dev-qa-db-ja.com

Angular 2-フォーム配列値を設定できません

私はこのエラーを受け取ります:

この配列に登録されているフォームコントロールはまだありません。 ngModelを使用している場合は、次の目盛りを確認することをお勧めします(例:setTimeoutを使用)。

このコードを使用する場合:

public settingsForm: FormGroup = this.fb.group({
  collaborators: this.fb.array([]),
  rsvp: this.fb.group({
    latestDate: ['', [Validators.required]],
    latestTime: ['', [Validators.required]],
    guestLimit: ['', [Validators.required]],
    isRSVPOpen: false,
    isGuestPlusOne: false,
    isAutoApproveToGuestlist: false,
    isOnlyFacebookRSVP: false,
    isBirthdayAndPhoneRequired: false
  }),
  tickets: this.fb.group({
    info: this.fb.group({
      closingDate: '',
      closingTime: ''
    }),
    types: this.fb.array([])
  })
});

内部ngOnInit

this.eventSubscription = this.af.database.object('/events/' + this.eventId)
  .filter(event => event['$value'] !== null)
  .subscribe((event: IEvent) => {

    const settings: ISettings = event.settings;
    const collaborators: ICollaborator[] = settings.collaborators;
    const rsvp: IRSVP = settings.rsvp;
    const tickets: ITickets = settings.tickets;

    this.settingsForm.setValue({
      collaborators: collaborators || [],
      rsvp: rsvp,
      tickets: {
        info: tickets.info,
        types: tickets.types || []
      }
    });
  }
);

collaboratorsに値が含まれている場合、つまり、undefinednullまたは空の[]ではない場合:

[
  {
    email: '[email protected]',
    role: 1
  },
  {
    email: '[email protected]',
    role: 2
  }
]

次に、setValueeventSubscription行でアプリがクラッシュします。

なぜこれが起こっているのか理解できません。

何か案は?

12
Chrillewoodz

コントロールでフォーム配列を初期化します。それで問題は解決します。その方法を知る必要がある場合は、 Reactive Forms ガイドを参照してください。 ngModelを使用している場合は、おそらく削除する価値があります。

1
Roman C

値を設定する前に、フォームOnInitを作成する必要があります。このようなものを試してください:

settingsForm: FormGroup; 

buildForm(): void {
   settingsForm: FormGroup = this.fb.group({
      //content of settingsForm
   })
}

ngOnInit() {
    this.buildForm();
    this.eventSubscription = this.af.database.object('/events/' + this.eventId)
    //...
    this.settingsForm.setValue({ //you can try .patchValue to set only available value
        //...
    })
}
1
mickdev

FormGroupまたはFormArrayでsetValue(data)を呼び出す前に、FormGroupまたはFormArrayはexactlyと同じ構造のdataを持っている必要があります。構造だけが重要であり、FormGroupまたはFormArrayの値はdataに置き換えられます。

例、データが

let data = [ {a: 1, b:2}, {a: 3, b: 4} ]

次に、FormArrayには2つのFormGroupが必要であり、各FormGroupにはaという1つのFieldControlとbという1つのFieldControlが必要です。あなたはこのようなことをすることができます:

let fa = this.formBuilder.array([
  this.formBuilder.group({a: 0, b:0}),
  this.formBuilder.group({a: 0, b:0})
])
fa.setValue(data)

データがより複雑な構造である場合、FormArrayは同じ複雑な構造を持つ必要があります。

0
Jingshao Chen

このコードが役立つと思います

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

export class SomeComponent implements OnInit {

consutructor(public  fb:FormBuilder) { }

    public buildcollaboratorsGroup(fb:FormBuilder):FormGroup {
        return fb.group({
                            email:'',
                            role:''
                });
    }

ngOnInit() {
    public settingsForm: FormGroup = this.fb.group({
    collaborators:this.fb.array([this.buildcollaboratorsGroup(this.fb)])
    });     

    this.setFormArrayValue();
 }


    // I am trying set only one value if it's multiple use foreach        
    public setFormArrayValue() {
        const controlArray = <FormArray> this.settingsForm.get('collaborators');
        controlArray.controls[0].get('email').setValue('[email protected]');
        controlArray.controls[0].get('role').setValue(2);
    }

    // I am trying remove only one value if it's multiple use foreach        
    public removeFormArrayValue() {
        const controlArray = <FormArray> this.settingsForm.get('collaborators');
           controlArray.removeAt(0);        
    }
}
0
Praveen M P