Kiedy używać FormGroup, a kiedy FormArray?

91

FormGroup :

FormGroup agreguje wartości każdego FormControl dziecka w jeden obiekt, z każdej nazwy kontrolnej jako klucza.

const form = new FormGroup({
  first: new FormControl('Nancy', Validators.minLength(2)),
  last: new FormControl('Drew')
});

FormArray :

FormArray agreguje wartości każdej FormControl dziecko w tablicy.

const arr = new FormArray([
  new FormControl('Nancy', Validators.minLength(2)),
  new FormControl('Drew')
]);

Kiedy należy używać jednego nad drugim?

jcroll
źródło

Odpowiedzi:

122

FormArray to odmiana FormGroup. Kluczową różnicą jest to, że jego dane są serializowane jako tablica (w przeciwieństwie do serializacji jako obiektu w przypadku FormGroup). Może to być szczególnie przydatne, gdy nie wiesz, ile kontrolek będzie obecnych w grupie, takich jak formularze dynamiczne.

Spróbuję wyjaśnić na krótkim przykładzie. Powiedzmy, że masz formularz, w którym rejestrujesz zamówienie klienta na pizzę. Umieszczasz przycisk, aby umożliwić im dodawanie i usuwanie wszelkich specjalnych życzeń. Oto część html komponentu:

<section>
  <p>Any special requests?</p>
  <ul formArrayName="specialRequests">
    <li *ngFor="let item of orderForm.controls.specialRequests.controls; let i = index">
      <input type="text" formControlName="{{i}}">
      <button type="button" title="Remove Request" (click)="onRemoveSpecialRequest(i)">Remove</button>
    </li>
  </ul>
  <button type="button" (click)="onAddSpecialRequest()">
    Add a Request
  </button>
</section>

a oto klasa komponentów definiująca i obsługująca specjalne żądania:

constructor () {
  this.orderForm = new FormGroup({
    firstName: new FormControl('Nancy', Validators.minLength(2)),
    lastName: new FormControl('Drew'),
    specialRequests: new FormArray([
      new FormControl(null)
    ])
  });
}

onSubmitForm () {
  console.log(this.orderForm.value);
}

onAddSpecialRequest () {
  this.orderForm.controls
  .specialRequests.push(new FormControl(null));
}

onRemoveSpecialRequest (index) {
  this.orderForm.controls['specialRequests'].removeAt(index);
}

FormArray oferuje większą elastyczność niż FormGroup w tym sensie, że łatwiej jest manipulować formantControls za pomocą "push", "insert" i "removeAt" niż przy użyciu formantów "addControl", "removeControl", "setValue" itd. FormArray. prawidłowo śledzone w hierarchii formularza.

mam nadzieję że to pomoże.

Usman
źródło
4
co jeśli próbujesz edytować formularze? Jak iterujesz i dodajesz kontrolki?
ctilley79
1
Jak można to zmienić na komponenty?
Justin,
Czy można dodać obiekty z klucz: wartość do tablicy formularza zamiast samych wartości?
Anthony
Jak możemy ustawić nazwę etykiety formularza? czy jest jakaś opcja do ustawienia podczas inicjowania formantu formularza? ponieważ formularz dynamiczny nie może ustawić jego wartości.
Krishnadas PC,
29

Do stworzenia formularzy reaktywnych niezbędny FormGroupjest rodzic . Może FormGroupto dalej zawierać formControls, child formGroupslubformArray

FormArraymoże ponadto zawierać tablicę formControlslub formGroupsiebie.

Kiedy powinniśmy używać formArray?

Przeczytaj ten piękny post, który wyjaśnia użycieformArray

Ciekawy przykład na tym blogu dotyczy wycieczek formGroup

Struktura wycieczek formGroupprzy użyciu formControli formArraywyglądałaby mniej więcej tak:

this.tripForm = this.fb.group({
    name: [name, Validators.required],
     cities: new FormArray(
       [0] ---> new FormGroup({
           name: new FormControl('', Validators.required),
               places: new FormArray(
                  [0]--> new FormGroup({
                      name: new FormControl('', Validators.required),
                         }),
                      [1]--> new FormGroup({
                         name: new FormControl('', Validators.required),
                      })
                  )
              }), 
       [1] ---> new FormGroup({
           name: new FormControl('', Validators.required),
           places: new FormArray(
               [0]--> new FormGroup({
                   name: new FormControl('', Validators.required),
               }),
               [1]--> new FormGroup({
                   name: new FormControl('', Validators.required),
               })
               )
      }))
})

Nie zapomnij, aby grać z tym DEMO , i zauważyć wykorzystanie macierzy do citiesi placesod wycieczkę.

Amit Chigadani
źródło
Krótkie i słodkie wyjaśnienie.
Kanchan
niesamowite wyjaśnienie
Taoufik Jabbari
Wspaniały brat.
jalpa
@scopchanov Może nie ma wiele wyjaśnień w tekście, ale reprezentacja struktury formularza daje pewien pomysł. Daj mi znać, jeśli jest coś, co możemy dodać, aby poprawić odpowiedź :)
Amit Chigadani
Cóż, jeśli ktoś powie „wyjaśnienie”, to spodziewam się dokładnie tego zobaczyć. Z całym moim szacunkiem, zgodnie z definicjami SO, Twoja odpowiedź jest bardzo zbliżona do odpowiedzi „tylko link”, ponieważ dokładnie tam, gdzie dochodzi do sedna sprawy, tj. Kiedy powinniśmy używać formArray? , podany jest link do posta na blogu, bez cytowania żadnej istotnej jego części. Rzeczywiście opublikowałeś jakiś kod, ale znowu nie ma żadnego wyjaśnienia. Gdybyś zacytował obie zasady z tego wpisu na blogu, zrobiłoby to ogromną różnicę.
scopchanov
5

Od: Książka Antona Moiseeva „Angular Development with Typescript, wydanie drugie”. :

Gdy musisz programowo dodać (lub usunąć) kontrolki do formularza , użyj FormArray . Jest podobny do FormGroup, ale ma zmienną długości . Podczas gdy FormGroup reprezentuje cały formularz lub ustalony podzbiór pól formularza , FormArray zwykle reprezentuje kolekcję kontrolek formularza, które mogą rosnąć lub zmniejszać się .

Na przykład możesz użyć FormArray, aby umożliwić użytkownikom wprowadzanie dowolnej liczby wiadomości e-mail.

HS Progr
źródło
0

Z dokumentacji kątowej widać to

FormArray jest alternatywą dla FormGroup do zarządzania dowolną liczbą nienazwanych kontrolek. Podobnie jak w przypadku wystąpień grupy formularzy, można dynamicznie wstawiać i usuwać kontrolki z instancji tablicy formularzy, a wartość instancji tablicy formularza i stan walidacji są obliczane na podstawie jej kontrolek podrzędnych. Nie musisz jednak definiować klucza dla każdej kontrolki według nazwy, więc jest to świetna opcja, jeśli nie znasz z góry liczby wartości podrzędnych.

Pokażę Ci ich przykład i spróbuję wyjaśnić, jak to rozumiem. Możesz zobaczyć źródło tutaj

Wyobraź sobie formularz, który ma następujące pola

  profileForm = this.fb.group({
    firstName: ['', Validators.required],
    lastName: [''],
    address: this.fb.group({
      street: [''],
      city: [''],
      state: [''],
      zip: ['']
    }),
    aliases: this.fb.array([
      this.fb.control('')
    ])
  });

Tutaj mamy firstName, lastName, addressa aliaseswszystkie pola są razem grupa forma więc zawinąć wszystko group. Jednocześnie addressjest jak podgrupa, więc zawijamy ją w inną group(możesz spojrzeć na szablon dla lepszego zrozumienia)! Każda kontrolka formularza jest tutaj keywyjątkiem aliasesi oznacza to, że możesz włożyć do niej wartości tak bardzo, jak chcesz, jak prosta tablica przy użyciu formBuildermetod takich jak push.

Tak to rozumiem, mam nadzieję, że to komuś pomoże.

Gh111
źródło