2017-07-13 4 views
5

私は反応型で角度4を使用しています。私は自分のコンポーネントで追跡している配列に結びつけようとしているフォーム配列を持っています。私は反応形式を使用しているので、検証ができるので、テンプレート形式のアプローチを使用したくありません。角度の配列で変更された項目のインデックスを取得する方法

私はそうのようなフォームの配列に項目を追加します。

createFormWithModel() { 
    this.orderForm = this.fb.group({ 
    orderNumber: [this.order.ProductBookingOrder], 
    orderDate: [this.order.PurchaseOrderIssuedDate], 
    lineDetailsArray: this.fb.array([]) 
    }) 

    const arrayControl = <FormArray>this.orderForm.controls['lineDetailsArray']; 
    this.order.ProductBookingDetails.forEach(item => { 
    let newGroup = this.fb.group({ 
     ProductName: [item.ProductName], 
     Quantity: [item.ProductQuantity.Quantity], 
     UOM: [item.ProductQuantity.UOM], 
     RequestedShipDate: [item.RequestedShipDate] 
    }) 
    }) 
} 

orderFormは明らかに私の反応性の形であるFormGroup。注文は自分のAPIから取得したオブジェクトで、ラインの詳細を含めてその値を更新したいと考えています。私はそれぞれのnewGroupで 'valueChanges.subscribe'を使うべきだと思いますが、変更された項目のインデックスを取得する方法がわかりません。何かご意見は?

 newGroup.valueChanges.subscribe('i want value and index some how' => { 
this.order.ProductbookingDetails[index].ProductName = value.ProductName; 
    }); 

は、ここでは、この部分のHTMLです:

<tbody formArrayName="lineDetailsArray"> 
     <tr [formGroupName]="i" *ngFor="let line of orderForm.controls['lineDetailsArray'].controls; index as i"> 
      <td><input class="form-control" type="text" placeholder="Product Name" formControlName="ProductName" required/></td> 
      <td><input class="form-control" type="number" step=".01" (focus)="$event.target.select()" placeholder="Quantity" formControlName="Quantity"/></td> 
      <td><input class="form-control" readonly formControlName="UOM"></td> 
      <td><date-picker formControlName="RequestedShipDate" format="L" [showClearButton]="false"></date-picker></td> 
      <td><button type="button" (click)="deleteLineDetail(i)">Remove</button></td> 
     </tr> 
     </tbody> 
+0

なぜ各行の詳細を保存しますか?なぜあなたは合計モデルを送ることができません – CharanRoot

+0

私はAPIから私の注文モデルを得る余分なものがたくさんありますが、私はorderFormモデルにそのようなものがほしいだけです。 orderFormモデルは、ユーザーが更新できる情報を更新できるようにするためのものです。ですから、私は、他のすべての情報が欠落しているため、完了した時点でorderFormモデルをAPIに送ることはできません。フォーム入力が変更されたときに私の注文モデルの値が更新されるようにします。 – Kevin

答えて

3

私はここにvalueChangesを使用することはありません、配列は、多くの値を持っている特別な場合には、過度に解雇されるだろう。

あなたはそれぞれの値に変更イベントを持っている、とだけ値とインデックス、

(keyup)="changeValue(line.controls.ProductName.value, i)" 

のようなものしかし、戦いのこの種の反応性フォームの目的を渡すことができます。

フォームに表示したくない値があり、ユーザーが変更できない値でも、フォームコントロールとしてフォームに追加するだけで、必要なことは何も表示されませんそれらをテンプレートで表示する!

このように、モデルorderと一致するようにフォームを作成すると、送信時にモデルに直接フォーム値を割り当てることができます。私はこのアプローチを強く勧めます。

+0

これは私がやったことです。私は各formArrayコントロールを循環し、私のラインディテールを再構築し、その新しいリストを私の注文リストに再割り当てしました。私はちょうど私のフォームを複雑なタイスクリプトオブジェクトに変えようとします。ありがとう! – Kevin

+0

問題ありません!そうですね、フォームを変更するだけで、変更イベントをキャプチャする必要がなくなります。私の意見では、よりクリーンで効果的です。幸運、幸せなコーディングと素晴らしい週末を持っている! :) – Alex

2
export class CustomFormArray { 
    public form: FormGroup; 

    public get someArray(): FormArray { 
      return this.form.get('someArray') as FormArray 
    } 

    constructor(private _fb: FormBuilder) { 
      this.form = _fb.group({ 
       someArray: _fb.array([]) 
      }); 

      this.someArray.controls.forEach(
       control => { 
        control.valueChanges.subscribe(
         () => { 
         console.log(this.someArray.controls.indexOf(control)) // logs index of changed item in form array 
         } 
        ) 
       } 
     ) 
    } 
}  
+2

このコードは質問に答えるかもしれませんが、どのようにして問題が解決されるのか、なぜそれが解決されるのかについての追加の文脈を提供することで、回答の長期的価値が向上します。 [コードのみの回答を投稿することは賢明ではありません](https://meta.stackexchange.com/a/148274/341145)の理由をお読みください。 –

関連する問題