Winkel 2: Iterieren Sie über reaktive Formkontrollen


Antworten:


193

Fand heraus, dass Object.keysdamit umgehen kann ..

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

Verwenden Sie für Angular 8+ Folgendes (basierend auf der Antwort von Michelangelo):

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

2
Wenn ich diese Funktion in onSubmit verwende, wird der Fehler angezeigt. Cannot invoke an expression whose type lacks a call signature. Type 'AbstractControl' has no compatible call signatures.Weiß jemand warum?
Maidi

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

Wenn ich Object.keys oder sogar das "for in" versuche, bekomme ich nichts. Wenn ich jedoch console.log (form.controls) verwende, kann ich alle verschiedenen Formularsteuerelemente sehen, die im Objekt enthalten sind. Ich bin verblüfft.
Jake Shakesworth

Bei Verwendung von Angular 5 wird markAsDirty () / markAsTouched () nicht in Unterformgruppen zurückgeführt. Ich habe den obigen Code in eine rekursive Funktion aufgeteilt und ihn in allen Unter-FormGroups aufgerufen. Funktioniert besser mit dem aktuellen Angular Material UI-Projekt, falls ein Benutzer ein erforderliches Element nie berührt. Ich nenne es, wenn der Benutzer versucht, das Formular zu senden, um eines an diesem Punkt zu markieren.
Robert

3
Vielen Dank für das Lesen meines Beitrags und das Aktualisieren Ihrer eigenen Antwort. Offizielle Dokumente sind ebenfalls veraltet, so dass ich dies herausfinden musste, indem ich jede Zeile druckte ...
Michelangelo

53

Für das, was es wert ist, gibt es eine andere Möglichkeit, dies zu tun, ohne Object.keys (...) Magie verwenden zu müssen:

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

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

}

Wie bekomme ich den Index der Schleife?
SVK

1
Für diejenigen, die TSLint verwenden, funktioniert der Code, aber TSLint beschwert sich mit "for (... in ...) -Anweisungen müssen mit einer if-Anweisung (forin) gefiltert werden".
Yennefer

1
tslint weist darauf hin, ein Zitat aus der JavaScript-Dokumentation der for ... in Anweisung stackoverflow.com/questions/40770425/…
Egle Kreivyte

39

Die akzeptierte Antwort ist für eine flache Formularstruktur korrekt, beantwortet jedoch die ursprüngliche Frage nicht vollständig. Für eine Webseite sind möglicherweise verschachtelte FormGroups und FormArrays erforderlich. Dies muss berücksichtigt werden, um eine robuste Lösung zu erstellen.

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();
        }
    });
}

wird instanceofimmer arbeiten , nachdem sie von Typoskript transpiled werden?
der bemerkenswerte

@ the-bemerkenswert instanceofist kein TypeScript-spezifisches Schlüsselwort ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ). Auch der classDatentyp ist nicht .
Keenan Diggs

6

Es scheint, dass die get Funktion zum Abrufen bestimmter Werte in Ihrem Formular in Angular 8 nicht mehr funktioniert. Daher habe ich sie auf der Grundlage der Antwort von @Liviu Ilea gelöst.

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

Bist du sicher? Das API-Dokument verfügt bereits über die get-Methode für Abstract Control ( angle.io/api/forms/AbstractControl#get ). Ich bin noch nicht migriert. Jetzt habe ich Angst (⊙_ ◎)
Alan Grosz

@AlanGrosz Ja, das habe ich auch gesehen, als ich es neu geschrieben habe, aber selbst beim Drucken aller Zeilen in der Konsole konnte ich keine get-Methode für das Objekt finden. Ich denke, die Dokumentation ist dahinter. Viel Glück beim Migrieren!
Michelangelo

Ich glaube nicht, dass sie es entfernt haben, bekommen Arbeiten für mich in Angular 8. Auch ist es noch in der Dokumentation angular.io/api/forms/AbstractControl#get
Laszlo Sarvold

6

Mit der Antwort von @Marcos habe ich eine Funktion erstellt, die als Übergabe einer formGroup als Parameter aufgerufen werden kann. Sie markiert alle untergeordneten FormGroup-Steuerelemente als verschmutzt, um sie beispielsweise an mehreren Stellen im Code verwendbar zu machen, an denen sie in einen Dienst eingefügt wird.

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

ich hoffe es hilft ;)


Perfekt! Zum Service hinzugefügt, zusammen mit ähnlichen Funktionen wie clearValidators, Untouch usw. Möglicherweise möchten Sie eine rekursive Prüfung für verschachtelte Steuerelemente hinzufügen, dies funktioniert jedoch vorerst. Vielen Dank!
mc01

5

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


3

Das ist es, was für mich funktioniert

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

Ich erstelle diese Funktion, um sie zu erstellen. * Ich habe ein Steuerelement mit dem Namen 'order' und übergebe ihm den Index.

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


updateFormData() {
    const control = <FormArray>this.form.controls['conditionGroups'];  
    control.value.map((x,index)=>{
    x.order = index; 
 })
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.