Winkel 2: Iterieren Sie über reaktive Formkontrollen

92

Ich möchte markAsDirtyalle Steuerelemente in einem FormGroup.

Marcos JC Kichel
quelle

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();
    });
Marcos JC Kichel
quelle
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  

}
Liviu Ilea
quelle
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();
        }
    });
}
Keenan Diggs
quelle
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);
}
Michelangelo
quelle
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 ;)

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

Foad
quelle
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);
    }
  });
}
Omyfish
quelle
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; 
 })
João Marcos Santos Teixeira
quelle