2016-11-07 22 views
1

テーブル(FormArray)に正しいフィールド名を設定するためにサービス応答を受け取るフォームがあります。正しいフォームフィールド名が与えられると、いくつかのパラメータのフィールドに別のデータベースへの別のサービスコールを設定しようとしています。Angular2 Formbuilder - FormArray要素を参照する

簡単な例:私たちは「プロパティを読み取ることができません 『コンソールにエラーを受信して​​い

ngOnInit() { 
    this.myForm = this._fb.group({ 
    name: [''], 
    myArray: this._fb.array([]) 
    }), 
    initArray(); 
} 
private initArray(){ 
    this.arrayValsService.getValues.subscribe(
    response => { 
        for (item of response) { 
        let arrayItemGroup = this.createItemGroup(item.code, item.value); 
        const control = <FormArray>this.myForm.controls['myArray']; 
        control.push(arrayItemGroup); 
        } 
       }, 
    err => {console.error(err);} 
    }; 
} 
private createItemGroup(code: string, value: string) { 
    return this._fb_group({ 
    selected: [false], 
    itemCode: [code], 
    itemValue: [value], 
    otherVal1: [''],  
    otherVal2: [''] 
    }); 
} 

private setArray() { 
    if(this.key !== undefined) { 
    this.dataService.getData(this.key).subscribe(
     response => { 
     this.myForm.patchValue(response); 
     for (let resItem of response.itemsSet) { 
      for (let formItem of <FormArray>this.myForm.controls['myArray']) { 
      if (formItem.controls.itemCode === resItem.code) { // <== ISSUE HERE 
       formItem.patchValue(response.itemsSet.resItem); 
       formItem.controls.selected.setValue(true); 
      } 
      } 
     } 
     err => {console.error(err);} 
    ); 
    } 
} 

は、上記の標線に発生した』、未定義の」制御します。私はそれに応じて値を更新するために配列内の個々のフォームコントロールグループを参照する必要があります。代わりに、forループネストを使用する、私はまた、配列要素群内の特定の制御を確認するためにarray.find使用しようとした:

const control = <FormArray>(this.myForm.controls['myArray']) 
    .find(item => myArray.controls.item.itemCode === resItem.code) 

これも動作していません。コントロールが未定義のプロパティであるという同じ問題が発生しました。結論は、私はformArrayの子要素とそれらの子それぞれのコントロールを参照する方法が必要です。

以下の方法は、formArray.controls配列オブジェクトを反復するために動作し、まだtypescriptですがエラーをコンパイル生成:

for (let resItem of response.itemsSet) { 
    const control = this.myForm.controls['myArray'].controls 
    .find((item:any) => item.value.itemCode === resItem.code); 
    if(control) {control.controls.selected.setValue(true); // ...other value updates 

controlは配列オブジェクトであるため、.find()は、ここで働いています。 の子(FormGroup型)内には、サービス応答を比較するコードを持つ別の配列オブジェクトchild.valueがあります。機能的には、これは意図した仕事をしています。しかし、私はまだエラーが発生しています: 'エラーTS2329:プロパティ'コントロール 'が' AbstractControl 'タイプに存在しません。'今後の参考のため

最終編集:FormArray自身とFormGroupを型キャスト

私は「発見」は初期typescriptですエラーを除去するのに有効だったんです。しかし、これを実行すると、私が更新していたフォームコントロールは、同じ "プロパティ 'コントロール'を 'AbstractControl'タイプのエラーで投げ始めました。 this questionに基づいて特定のコントロールを参照するための形式を変更しました。

最終結果:

for (let resItem of response.itemsSet) { 
     const control = (<FormGroup>((<FormArray>(this.myForm.controls['myArray'])).controls 
     .find((item:any) => item.value.itemCode === resItem.code))); 
     if(control) {control.controls['selected']setValue(true); // ...other value updates 

重要ポイント:型キャストFormGroups、FormArrays。 ['control']形式で明示的に指定されたコントロールを参照します。

答えて

1

formItem変数はFormControlではありません。ソリューションは、その後、直接FormArray上のコントロール配列にアクセスし、反復することです:

for (let formItem of <FormArray>this.myForm.controls['myArray'].controls) { 
    if ((<FormGroup>formItem).controls['itemCode'] === resItem.code) { 
      <...> 
      (<FormGroup>formItem).controls['selected'].setValue(true); 
    } 
} 

他の方法は、あなたがそれらをログに記録した場合にポップアップする「未定義」の束を持っている必要があります。ここで

は、この繊細を実証plunkerです:あなたの活字体のエラーの場合http://plnkr.co/edit/JRbrPR2g2Kl3z6VJV5jQ?p=preview

、あなたがコンパイラよりもよく知っているならば、あなたはキャストする必要があるとしています。

ここでは、findバージョンのものです。このパターンに続き

(<FormGroup>control).controls['selected'].setValue(true); 
+0

は、TSエラーのカップルに私を導いた:タイプ「FormArray」は配列または文字列ではありません。プロパティ 'controls'は型 'AbstractControl'には存在しません。あなたのplnkrでは '['myArray']。controls'を' 'とキャストしていません(そして、それは配列型であると思います)。私はそのキャストを削除しましたが、依然としてAbstractControl型のエラーを受け取り、このメソッドは予期した結果を生成しません。機能的には十分だが同じエラーが発生する方法で質問を編集します。 –

+0

キャストしようとしましたか?コンパイラよりも優れていると分かっているなら、それを伝える必要があります。サンプルを提供するための答えを更新しました。 – silentsod

関連する問題