2017-07-13 129 views
5

我正在使用反应形式的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> 
+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) –

相关问题