2016-06-21 13 views
13

Zasadniczo chcę utworzyć dynamiczną formę z zagnieżdżonych obiektów, takich jak na obrazku poniżej: Angular 2 Nested Form Examplekątowa 2 Dynamiczny Zagnieżdżony Formularz

  • płatna offs są w tablicy na wzór
  • powinniśmy być w stanie dodać/usuń spłaty w razie potrzeby.
  • Formularz powinien zsynchronizować podstawowych kontrolek formularzy i modelować
  • liczba płatnych off jest arbitralne i powinny być załadowane do formy z modelu

Brak przykłady pracy, że mogę znaleźć jak jak zrobić w kątowej 2, chociaż to było naprawdę łatwe do zrobienia w Kątowymi 1.


Poniżej jest moje pierwotne pytanie, mam go od zaktualizowane do wyjaśnienia (patrz wyżej):

Po pierwsze chciałem tylko podkreślić, że jestem świadomy, że nowa wersja Angular 2 rc.2 została wydana kilka dni temu. Zatem kod do tworzenia dynamicznej, zagnieżdżonej formy mógł się nieco zmienić, ale nie ma wystarczającej dokumentacji, aby to zrozumieć.

W najnowszej wersji (ów) kątowego 2 (obecnie używam rc.1 ale planuje aktualizację do rc.2) muszę utworzyć formularz tak (pseudo-kod widzenia):

<form [ngFormModel]="form" (ngSubmit)="onSubmit()"> 
    <input type="text" ngControl="name"> 

    <div *ngFor="let expense for expenses; let i = index;" control-group="expenses"> 
    <input type="text" ngControl="expense.amount" [(ngModel)]="myModel.expenses[i].amount"> 
    <input type="checkbox" ngControl="expense.final" [(ngModel)]="myModel.expenses[i].final"> 
    </div> 

    <a class="button" (click)="addExpenseControl()">Add</a> 
    <a class="button" (click)="deleteExpenseControl()">Delete</a> 
</form> 

Tak więc powyższy pseudo-kod nie zadziała, ale szczerze mówiąc z powodu braku dokumentacji nie mogę wymyślić, jak podłączyć coś takiego. Jest kilka samouczków dotyczących zagnieżdżonej ControlGroup, ale nie będzie to pasować do tej sytuacji, ponieważ musimy mieć możliwość dynamicznego dodawania i usuwania grup kontrolnych, a także potrzebuję ich synchronizować z modelem.

Znalazłem plunkr tutaj dostarczone przez Kątowymi zespołu, który umożliwia dodawanie formantów do formularza - ale nie jest to dodawanie/usuwanie ControlGroup, a to za pomocą ControlArray i nie jestem pewien, czy to odnosi się tutaj?

Jestem bardzo obeznana z użyciem nowszych form Angular 2 opartych na modelu, jednak potrzebuję zasobów, aby poprawnie je zagnieździć (dynamicznie!) I powiązać te zagnieżdżone dane z głównym modelem formularza. Jak odnieść się do zagnieżdżonych formantów w widoku? Czy pseudo-kod powyżej jest nawet bliski? Wpisałbym kod z kontrolera, ale szczerze mówiąc nie wiedziałbym, od czego zacząć, jeśli chodzi o zagnieżdżone wydatki (ControlGroup?) Powyżej ...

+0

'ControlGroup 'jest zupełnie taki sam jak kontrolka i jestem pewien, że możesz go dodać w taki sam sposób. –

+0

Myślałem o tym samym, ale pytanie pozostaje, nawet jeśli tak jest - jaki kod umieszczam dla 'ngControl =" .. "' i '[(ngModel)] =" ... "', aby poprawnie podłączyć to w górę? – FireDragon

Odpowiedz

14

Musiałem to sobie wyobrazić, ponieważ wydaje mi się formy te ciągle się zmieniają w Angular 2 i nie widziałem innych podobnych przykładów (chociaż wydaje się, że jest to bardzo powszechny przypadek użycia).

Here is a plunkr roboczego przykładu za pomocą Angular2 RC3.

Używam zaktualizowanego kodu formularza Angular 2 z this document.

app.component.TS (zawiera postać):

import { Component } from '@angular/core'; 
import {REACTIVE_FORM_DIRECTIVES, FormControl, FormGroup, FormArray} from '@angular/forms'; 

@Component({ 
    selector: 'my-app', 
    templateUrl: 'app/app.html', 
    directives: [REACTIVE_FORM_DIRECTIVES], 
    providers: [] 
}) 
export class AppComponent { 
    form: FormGroup; 
    myModel:any; 

    constructor() { 
    // initializing a model for the form to keep in sync with. 
    // usually you'd grab this from a backend API 
    this.myModel = { 
     name: "Joanna Jedrzejczyk", 
     payOffs: [ 
     {amount: 111.11, date: "Jan 1, 2016", final: false}, 
     {amount: 222.22, date: "Jan 2, 2016", final: true} 
     ] 
    } 

    // initialize form with empty FormArray for payOffs 
    this.form = new FormGroup({ 
     name: new FormControl(''), 
     payOffs: new FormArray([]) 
    }); 

    // now we manually use the model and push a FormGroup into the form's FormArray for each PayOff 
    this.myModel.payOffs.forEach( 
     (po) => 
     this.form.controls.payOffs.push(this.createPayOffFormGroup(po)) 
    ); 
    } 

    createPayOffFormGroup(payOffObj) { 
    console.log("payOffObj", payOffObj); 
    return new FormGroup({ 
     amount: new FormControl(payOffObj.amount), 
     date: new FormControl(payOffObj.date), 
     final: new FormControl(payOffObj.final) 
    }); 
    } 

    addPayOff(event) { 
    event.preventDefault(); // ensure this button doesn't try to submit the form 
    var emptyPayOff = {amount: null, date: null, final: false}; 

    // add pay off to both the model and to form controls because I don't think Angular has any way to do this automagically yet 
    this.myModel.payOffs.push(emptyPayOff); 
    this.form.controls.payOffs.push(this.createPayOffFormGroup(emptyPayOff)); 
    console.log("Added New Pay Off", this.form.controls.payOffs) 
    } 

    deletePayOff(index:number) { 
    // delete payoff from both the model and the FormArray 
    this.myModel.payOffs.splice(index, 1); 
    this.form.controls.payOffs.removeAt(index); 
    } 
} 

Pamiętaj, że powyżej ręcznie wcisnąć nowych obiektów FormGroup w tablicy form.controls.payOffs, który jest FormArray obiektu.

app.html (zawiera formularz HTML):

<form (ngSubmit)="onSubmit()" [formGroup]="form"> 

    <label>Name</label> 
    <input type="text" formControlName="name" [(ngModel)]="myModel.name" placeholder="Name"> 

    <p>Pay Offs</p> 
    <table class="simple-table"> 
     <tr> 
     <th>Amount</th> 
     <th>Date</th> 
     <th>Final?</th> 
     <th></th> 
     </tr> 
    <tbody> 
     <tr *ngFor="let po of form.find('payOffs').controls; let i = index"> 
     <td> 
      <input type="text" size=10 [formControl]="po.controls.amount" [(ngModel)]="myModel.payOffs[i].amount"> 
     </td> 
     <td> 
      <input type="text" [formControl]="po.controls.date" [(ngModel)]="myModel.payOffs[i].date"> 
     </td> 
     <td> 
      <input type="checkbox" [formControl]="po.controls.final" [(ngModel)]="myModel.payOffs[i].final"> 
     </td> 
     <td> 
      <button (click)="deletePayOff(i)" style="color: white; background: rgba(255, 0, 0, .5)">x</button> 
     </td> 
     </tr> 
    </tbody> 
    <tr> 
     <td colspan="4" style="text-align: center; padding: .5em;"> 
     <button (click)="addPayOff($event)" style="color: white; background: rgba(0, 150, 0, 1)">Add Pay Off</button> 
     </td> 
    </tr> 
    </table> 

    </form> 

W formularzu html połączyć formę do modelu na wejściach z wypowiedzi tak:

... [formControl]="po.controls.amount" [(ngModel)]="myModel.payOffs[i].amount" ... 
+0

użyłem metody 'find' w html, aby znaleźć kontrolę, ale w przypadku' .ts', tj. 'Strona kontrolera' angular2 nie może znaleźć kontroli i zgłasza błąd' nie może odczytać właściwości push z undefined' dlaczego? tutaj jest cały problem http://stackoverflow.com/q/39349261/5043867 ,, dzięki z góry –

+0

@PardeepJain jeśli otrzymujesz błąd, o którym wspomniałeś, oznacza to, że dowolna postać FormArray, którą próbujesz nazywać 'push' on jest po prostu 'undefined' w pewnym momencie twojego kodu. Domyślam się, że FormArray nie jest jeszcze tworzony, a następnie próbujesz przesunąć grupę FormGo na "nic". Czy to już działa? Czy próbowałeś mojego podejścia do rzeczy? Moje podejście wykorzystuje formy * Model Driven *, więc zachowuję synchroniczny model kątowy z danymi oraz z obiektem formularza. – FireDragon

+1

Dla osób, które wciąż szukają dobrego tutoriala na ten temat, znalazłem ten (https://scotch.io/tutorials/how-to-build-nested-model-driven-forms-in-angular- 2 # part-2-move-address-to-a-new-component) Mam nadzieję, że to pomaga – ncohen