Kątowy 2: Iteruj po reaktywnych kontrolkach formularza


Odpowiedzi:


198

Okazało się, że Object.keyssobie z tym poradzę

    Object.keys(this.form.controls).forEach(key => {
      this.form.get(key).markAsDirty();
    });

W przypadku Angular 8+ użyj następującego (na podstawie odpowiedzi Michała Anioła):

    Object.keys(this.form.controls).forEach(key => {
      this.form.controls[key].markAsDirty();
    });

2
Kiedy używam tej funkcji w onSubmit, pojawia się błąd. Cannot invoke an expression whose type lacks a call signature. Type 'AbstractControl' has no compatible call signatures.Czy ktoś wie dlaczego?
maidi

1
Object.keys (this.registerForm.controls) .forEach (key => {this.registerForm.controls [klucz] .markAsDirty ();});
Foad

Kiedy próbuję Object.keys lub nawet „for in”, nic nie dostaję. Jednak jeśli korzystam z console.log (form.controls), mogę ZOBACZYĆ wszystkie różne kontrolki formularza zawarte w obiekcie. Jestem zdumiony.
Jake Shakesworth

Używając Angular 5, markAsDirty () / markAsTouched () nie powtarza się w żadnych sub-FormGroups. Przekształciłem powyższy kod w funkcję rekurencyjną i wywołałem go na dowolnych sub-FormGroups. Działa lepiej z bieżącym projektem Angular Material UI na wypadek, gdyby użytkownik nigdy nie dotknął wymaganego elementu, nazywam to, gdy użytkownik próbuje przesłać formularz, aby zaznaczyć dowolny w tym momencie.
Robert,

3
Dziękuję za przeczytanie mojego postu i zaktualizowanie własnej odpowiedzi. Oficjalne dokumenty również są nieaktualne, więc musiałem to rozgryźć, drukując każdą linię ...
Michelangelo

56

Warto, jest inny sposób na zrobienie tego bez konieczności używania magii Object.keys (...) :

for (const field in this.form.controls) { // 'field' is a string

  const control = this.form.get(field); // 'control' is a FormControl  

}

jak uzyskać indeks pętli?
SVK

1
Dla tych, którzy używają TSLint, kod działa, ale TSLint narzeka, że ​​„instrukcje for (... in ...) muszą być filtrowane za pomocą instrukcji if (forin)”.
Yennefer

1
tslint wskazuje, cytat z dokumentacji JavaScript instrukcji for ... in stackoverflow.com/questions/40770425/ ...
Egle Kreivyte

41

Przyjęta odpowiedź jest prawidłowa dla płaskiej konstrukcji formy, ale nie odpowiada w pełni na pierwotne pytanie. Strona internetowa może wymagać zagnieżdżonych FormGroups i FormArrays i musimy wziąć to pod uwagę, aby stworzyć solidne rozwiązanie.

public markControlsDirty(group: FormGroup | FormArray): void {
    Object.keys(group.controls).forEach((key: string) => {
        const abstractControl = group.controls[key];

        if (abstractControl instanceof FormGroup || abstractControl instanceof FormArray) {
            this.markControlsDirty(abstractControl);
        } else {
            abstractControl.markAsDirty();
        }
    });
}

będzie instanceofzawsze działać po transpozycji przez maszynopis?
znaczący

@ the-notable instanceofnie jest słowem kluczowym specyficznym dla języka TypeScript ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) Nie jest też classtypem danych.
Keenan Diggs

8

Korzystając z @Marcos answer, stworzyłem funkcję, którą można nazwać przekazując parametr formGroup jako parametr i zaznacza ona wszystkie kontrolki podrzędne formGroup jako brudne, aby umożliwić jej użycie z większej liczby miejsc w kodzie, na przykład umieszczając ją w usłudze.

public touchAllFormFields(formGroup: FormGroup): void {
    Object.keys(formGroup.controls).forEach((key) => {
        formGroup.get(key).markAsDirty();
    });
}

mam nadzieję, że to pomoże ;)


Idealny! Dodano do usługi, wraz z podobnymi funkcjami do clearValidators, untouch itp. Może chcieć dodać rekurencyjne sprawdzanie zagnieżdżonych kontrolek, ale to działa na razie. Dzięki!
mc01

6

Wygląda na to, że get funkcja nie działa już przy pobieraniu określonych wartości w formularzu w Angular 8, więc tak to rozwiązałem na podstawie odpowiedzi @Liviu Ilea.

for (const field in this.myForm.controls) { // 'field' is a string
  console.log(this.myForm.controls[field].value);
}

Jesteś pewny? Dokumentacja API ma już metodę get dla Abstract Control ( angular.io/api/forms/AbstractControl#get ). Jeszcze nie migrowałem. Teraz się boję (⊙_ ◎)
Alan Grosz

@AlanGrosz Tak, też to widziałem, przepisując to, ale nawet podczas drukowania wszystkich linii w konsoli nie mogłem znaleźć metody get na obiekcie. Myślę, że dokumentacja jest w tyle. Powodzenia w migracji!
Michelangelo

Nie sądzę, żeby go usunęli, zdobądź dla mnie prace w Angular 8. Również jest nadal w dokumentacji angular.io/api/forms/AbstractControl#get
Laszlo Sarvold

5

    Object.keys( this.registerForm.controls).forEach(key => {
       this.registerForm.controls[key].markAsDirty();
    });


4

To właśnie działa dla mnie

private markFormGroupTouched(formGroup: FormGroup) {
  Object.keys(formGroup.controls).forEach((key) => {
    const control = formGroup.controls[key];
    control.markAsDirty();
    if ((control instanceof FormGroup)) {
      this.markFormGroupTouched(control);
    }
  });
}

1

Tworzę tę funkcję, aby * * Mam kontrolkę z nazwą 'order' i przekazałem mu indeks.

{"conditionGroups": [
   {
     "order": null,
     "conditions": []
   }
  ]
}


updateFormData() {
    const control = <FormArray>this.form.controls['conditionGroups'];  
    control.value.map((x,index)=>{
    x.order = index; 
 })
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.