私はAngular 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>
ここではvalueChanges
を使用しません。特に配列に多くの値がある場合、過度に起動されます。
各値に変更イベントを設定し、値とインデックスを渡すだけです。
(keyup)="changeValue(line.controls.ProductName.value, i)"
しかし、この種の戦いは、リアクティブフォームの目的と戦います。
フォームに表示したくない値がたくさんあり、ユーザーが変更できない値であっても、とにかくフォームコントロールとしてフォームに追加するだけで、表示する必要があるとは言いませんテンプレート!
このようにして、モデルorder
に一致するようにフォームを構築する場合、送信時にフォームの値をモデルに直接割り当てることができます。このアプローチを強くお勧めします。
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
}
)
}
)
}
}
フォーム配列に保持するアイテム用に独自のコンポーネントを作成できます。更新、削除などのたびに、親コンポーネントにイベントを発行し、親コンポーネントでバインドしたイベントで発行するか、テンプレートの親コンポーネントにもインデックスを作成して使用できます。子コンポーネントの変更イベントでバインドするために使用する関数の追加入力パラメーター。
この記事を読んで、あなたが私が意味することを理解するでしょう:
https://medium.com/spektrakel-blog/angular2-building-nested-reactive-forms-7978ecd145e4