2017-07-13 19 views
5

Używam Angular 4 z formami reaktywnymi. Mam tablicę formularzy, którą próbuję powiązać z tablicą śledzoną w moim komponencie. Używam formularzy reaktywnych, więc mogę mieć walidację, więc nie chcę używać metody formularzy szablonów.Jak uzyskać indeks zmienionego elementu w postaci tablicy kątowej

dodać elementy do tablicy postać tak:

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] 
    }) 
    }) 
} 

Zlecenie Reklamowe jest oczywiście moja reaktywne formy FormGroup. kolejność jest moim obiektem, który otrzymuję z mojego API i chcę zaktualizować jego wartości, w tym szczegóły linii. Myślę, że powinienem używać "valueChanges.subscribe" na każdej nowej grupie, ale nie jestem pewien, jak uzyskać indeks elementu, który został zmieniony. jakieś pomysły?

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

Oto HTML dla tej części:

<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

dlaczego chcesz zapisać poszczególne szczegóły linii? dlaczego nie możesz wysłać całego modelu? – CharanRoot

+0

Jest mnóstwo dodatkowych rzeczy Mam model zamówienia z API, ale chcę tylko niektóre z tych rzeczy w modelu orderForm. Model orderForm jest taki, że mogę aktualizować informacje, które mogą być aktualizowane przez użytkownika. Więc nie mogę po prostu wysłać modelu orderForm do API, gdy wszystko jest zrobione, ponieważ będzie brakowało wszystkich innych informacji. Chcę, aby wartości mojego modelu zamówienia były aktualizowane, gdy zmiany w formularzu zmienią się. – Kevin

Odpowiedz

3

nie użyłby valueChanges tutaj, byłoby nadmiernie zwolniony, szczególnie jeśli tablica ma wiele wartości.

Można mieć zdarzenie zmiany na każdej wartości, i po prostu przekazać wartość i indeks, coś

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

ale tego rodzaju walkach Celem formie biernej.

Mimo że masz wiele wartości, których nie chcesz wyświetlać w formularzu, a wartości, których użytkownik nie może modyfikować, dodałem je do formularza mimo to jako formanty formularzy, nic nie mówi, że potrzebujesz aby pokazać je w szablonie!

W ten sposób, jeśli skompilujesz formularz w taki sposób, aby pasował do Twojego modelu order, możesz po prostu przesłać wartość formularza do swojego modelu po przesłaniu. Gorąco polecam to podejście.

+0

Właśnie to zrobiłem, coś w rodzaju. Przejrzałem każdą kontrolkę formArray i przebudowałem mój szczegół linii i ponownie przypisałem tę listę do mojej listy szczegółów zamówienia. Spróbuję teraz prosto przekształcić moją formę w mój skomplikowany obiekt maszynopisu. Dzięki! – Kevin

+0

Bez problemu! Tak, myślę, że dobrze jest po prostu zmodyfikować formularz jako taki i pozbyć się konieczności przechwytywania zmian. Moim zdaniem czystsze i bardziej skuteczne. Powodzenia, szczęśliwego kodowania i miłego weekendu! :) – 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

Chociaż ten kod może odpowiedzieć na pytanie, zapewnienie dodatkowego kontekstu dotyczącego tego, jak i/lub dlaczego rozwiązuje problem, poprawiłoby długoterminową wartość odpowiedzi. Przeczytaj, dlaczego [nie jest mądra publikacja odpowiedzi tylko kodu] (https://meta.stackexchange.com/a/148274/341145) –