typescript - Angular 2: Åtkomst till data från FormArray


Jag har förberett ett formulär med ReactiveForms som tillhandahålls av angular2/forms. Detta formulär har en form array products:

this.checkoutFormGroup = this.fb.group({
            selectedNominee: ['', Validators.required],
            selectedBank: ['', Validators.required],
            products: productFormGroupArray
        });

productFormGroupArray är en array av FormGroup-objekt. Jag hämtade kontrollerna, dvs. FormArray-objektet, med detta:

this.checkoutFormGroup.get('products')

Jag försöker få elementet i produktarrayen vid index i. Hur kan detta göras utan att loopa igenom arrayen?

Redigera:

Jag försökte med metoden at(index) som är tillgänglig:

this.checkoutFormGroup.get('products').at(index)

men detta genererar ett fel som:

Property 'at' does not exist on type 'AbstractControl'.

Redigera 2: checkoutData och fund tas emot från servern.

this.checkoutData.products.forEach(product => {
                    this.fundFormGroupArray.push(this.fb.group({
                        investmentAmount: [this.fund.minInvestment, Validators.required],
                        selectedSubOption: ['', Validators.required],
                    }))
            });

Svar #1

Kasta bara den kontrollen till en array

var arrayControl = this.checkoutFormGroup.get('products') as FormArray;

och alla dess funktioner finns där

var item = arrayControl.at(index);

Svar #2

Angular 14

Angular-användare, gläd er, eftersom sedan Angular v14 kan ni skriva FormGroup, FormArray och FormControl, vilket betyder att ni inte längre behöver göra typomvandling av AbstractControl-objekten.

Med den givna koden:

const formGroup = new FormGroup({
  list: new FormArray([
    new FormControl('first'),
    new FormControl('second'),
  ]),
});

Du kan nu direkt göra:

const firstValue = formGroup.controls.list.at(0); // string | null
const secondValue = formGroup.controls.list.at(1); // string | null

Om du vill ha en striktare typning som utesluter värdet null, kan du skapa din FormControl med alternativet nonNullable inställt på true:

const control = new FormControl('value', {nonNullable: true});
const value = control.value; // string

Angular 13,12,11 och tidigare (exklusive 1)

Även om att kasta AbstractControl till en FormArray innan man använder at()-metoden är ett sätt att göra det på, har jag inte sett någon påpeka att man också kan göra det med get()-metoden, vilket inte kräver någon typomvandling.

Enligt Angulars dokumentation är signaturen för get():
get(path: string | (string | number)[]): AbstractControl | null

Vilket betyder att du också kan komma åt FormArrays kontroller med det.

Exempel :

const formGroup = new FormGroup({
  list: new FormArray([
    new FormControl('first'),
    new FormControl('second'),
  ]),
});

const firstValue = formGroup.get('list.0').value; // Returns 'first'
const secondValue = formGroup.get('list.1').value; // Returns 'second'

Det här är verkligen användbart, när du vill binda en FormControl i HTML, där du inte kan kasta något:

<input [formControl]="formGroup.get('list.0')">

Här är en sammanfattning av sätt att göra det:

const firstControl = listControl.get('list.0');
const firstControl = listControl.get(['list', 0]);
const firstControl = listControl.get('list').get('0'); // You need a string and not a number
const listControl = formGroup.get('list') as FormArray;
const firstControl = listControl.at(0);

Svar #3

Enradare som ett alternativ till det nuvarande accepterade svaret

var item = (<FormArray>this.checkoutFormGroup.get('products')).at(index);

Relaterade artiklar