Winkel 2: Formularübermittlung abgebrochen, da das Formular nicht verbunden ist

80

Ich habe ein Modal, das ein Formular enthält. Wenn das Modal zerstört wird, wird in der Konsole der folgende Fehler angezeigt:

Das Senden des Formulars wurde abgebrochen, da das Formular nicht verbunden ist

Das Modal wird einem <modal-placeholder>Element hinzugefügt, das direkt <app-root>meinem untergeordneten Element untergeordnet ist.

Was ist der richtige Weg, um ein Formular aus dem DOM zu entfernen und diesen Fehler in Angular 2 zu beseitigen? Ich benutze derzeitcomponentRef.destroy();

Nick
quelle
Hattest du ein * ngIf, das das Formular ein- und ausblendet?
Mickdev
@mickdev no * ngWenn ich das Modal so zerstöre componentRef.destroy();, habe ich meiner Frage weitere Details hinzugefügt. Vielen Dank!
Nick
2
@ Mickdev Was soll ich tun, wenn ich * ngif verwende, um das Formular auszublenden und
anzuzeigen

Antworten:

174

Es kann andere Gründe dafür geben, aber in meinem Fall hatte ich eine Schaltfläche, die vom Browser als Senden-Schaltfläche interpretiert wurde, und daher wurde das Formular gesendet, als auf die Schaltfläche geklickt wurde, was den Fehler verursachte. Durch Hinzufügen von type = "button" wurde das Problem behoben. Vollständiges Element:

    <button type="button" (click)="submitForm()">
Erik Lindblad
quelle
33
Ich bin nicht sicher, warum diese Antwort akzeptiert wurde, da Sie dadurch die Möglichkeit verlieren, die Eingabetaste zu drücken, um das Formular zu senden.
Peter LaBanca
7
Die Antwort von Nour ist die einfachste und ermöglicht die Eingabe der Taste.
Heiner
2
Dies hat mein Problem behoben, bei dem ich eine CANCEL-Schaltfläche in das Formular implementiert habe, mit der das Formular über eine * ngIf-Direktive von der Seite entfernt wurde. Ich habe eine SAVE-Schaltfläche, die die Logik auslöst, um auch das Formular zu entfernen (bei erfolgreichem Speichern), aber diese Fehlermeldung wurde nie angezeigt, obwohl ich nicht den Typ = 'button' habe.
AlanObject
3
In meinem Fall trat dieser Fehler auf einer Schaltfläche Abbrechen auf, daher ist es gut, dass ich die type="button":)
Marcos Lima
Ich denke, diese Antwort ist insofern gut, als Sie in Ihren Formularen explizit angeben sollten, welche Schaltfläche die Schaltfläche zum Senden ist. Es behebt das Problem, dass die falsche Schaltfläche für die Übermittlung verwendet wird, und ermöglicht es Ihnen, die Eingabetaste weiterhin für die Übermittlung zu verwenden.
Justin
80

In das Formular-Tag sollten Sie Folgendes schreiben:

 <form #myForm="ngForm" (ngSubmit)="onSubmit()">

und innerhalb des Formulars sollten Sie die Schaltfläche "Senden" haben:

 <button type="submit"></button>

Und vor allem, wenn Sie andere Schaltflächen in Ihrem Formular haben, sollten Sie type="button"diese hinzufügen . Das Verlassen des Standardattributs type(was ich denke submit) führt zur Warnmeldung.

<button type="button"></button>
Nour
quelle
2
Ich denke, # myForm = "ngForm" ist nicht erforderlich.
Heiner
Sie haben Recht, es sei denn, Sie benötigen den Verweis auf das ngForm, es ist nicht erforderlich.
Nour
Dies ist der richtige Weg, um es zu lösen. Dadurch wird die Nachricht entfernt, während die Möglichkeit zum Senden durch Drücken der Eingabetaste erhalten bleibt.
William Stevens
24

Also bin ich heute tatsächlich auf genau das gleiche Problem gestoßen, außer ohne Modal. In meinem Formular habe ich zwei Schaltflächen. Eine, die das Formular sendet, und eine, die beim Klicken zur vorherigen Seite zurückleitet.

<button class="btn btn-default" routerLink="/events">Cancel</button>
<button type="submit" class="btn btn-primary">Submit</button>

Das Klicken auf die erste Schaltfläche mit dem RouterLink bewirkt genau das, was es soll, versucht aber anscheinend auch, das Formular zu senden, und muss dann die Formularübermittlung abbrechen, da die Seite, auf der sich das Formular befand, während der Übermittlung vom DOM abgemeldet wird.

Dies scheint genau das gleiche zu sein, was Ihnen passiert, außer mit einem Modal anstelle der gesamten Seite.

Das Problem wird behoben, wenn Sie den Typ der zweiten Schaltfläche direkt als etwas anderes als Senden angeben.

<button type="button "class="btn btn-default" routerLink="/events">Cancel</button>

Wenn Sie also das Modal über eine Schaltfläche "Abbrechen" oder etwas Ähnliches schließen, sollte die Angabe des oben gezeigten Typs dieser Schaltfläche Ihr Problem lösen.

Darkrender
quelle
6

Im Formularelement müssen Sie die Submit-Methode (ngSubmit) definieren, etwa: <form id="currency-edit" (ngSubmit)="onSubmit(f.value)" #f="ngForm">

und auf der Schaltfläche "Senden" lassen Sie die Klickmethode weg, da Ihr Formular jetzt mit der Methode "Senden" verbunden ist: <button class="btn btn-success" type="submit">Save</button>Die Schaltfläche sollte vom Typ "Senden" sein.

In dem Code hinter der Komponente implementieren Sie die Methode "onSubmit", zum Beispiel: onSubmit(value: ICurrency) { ... } Diese Methode empfängt ein Wertobjekt mit Werten aus den Formularfeldern.

Igor Babic
quelle
Vielen Dank, dies sollte die akzeptierte Antwort sein, wenn Sie weiterhin button type = "
submit
4

Für den Fall, dass das Absenden des Formulars mit der Zerstörung der Komponente einhergeht, schlägt das Absenden des Formulars unter Race-Bedingungen fehl, wenn das Formular vom DOM getrennt wird. Sagen wir, wir haben

submitForm() {
  if (this.myForm.invalid) {
    return;
  }
  this.saveData(); // processing Form data
  this.abandonForm(); // change route, close modal, partial template ngIf-destroying etc
}

Wenn saveDataes asynchron ist (zum Beispiel werden die Daten per API-Aufruf gespeichert), können wir auf das Ergebnis warten:

submitForm() {
  this.saveDataAsync().subscribe(
    () => this.abandonForm(),
    (err) => this.processError(err) // may include abandonForm() call
  );
}

Wenn Sie das Formular sofort verlassen müssen, sollte auch ein Ansatz ohne Verzögerung funktionieren. Dies garantiert, dass sich die DOM-Trennung in der nächsten Ereignisschleife befindet, nachdem die Formularübermittlung aufgerufen wurde:

submitForm() {
  this.saveData();
  setTimeout(() => this.abandonForm());
}

Dies sollte unabhängig vom Schaltflächentyp funktionieren.

Dhilt
quelle
1

Ich hatte dieses Problem vor kurzem und event.preventDefault()arbeitete für mich. Fügen Sie es Ihrer Klickereignismethode hinzu.

<button type="submit" (click)="submitForm($event)" mat-raised-button>Save</button>

Und:

submitForm(event: Event) {
  event.preventDefault();
  // ...
}
Abubakar Ibrahim
quelle
2
Diese Antwort enthält nicht genügend Details. Bitte erläutern Sie überzeugend, wie sich diese Lösung von den anderen aufgeführten unterscheidet oder besser ist, da dieser Beitrag bereits mehrere Lösungen enthält. Bitte lesen Sie die SO-Richtlinien, bevor Sie Beiträge veröffentlichen.
Zündkerze
1
@sparkplug nicht Gatekeep, diese Antwort war nützlich, auch wenn es mehr Details brauchte.
Will Shaver
Will Shaver - Nützlich vielleicht. Gut formatiert und leicht zu interpretieren, nicht so sehr. Es gibt Standards, die sicherstellen, dass Antworten für einen SO-Benutzer leicht zu lesen und zu verstehen sind. Die Antwort von @dhilt ist ein Beispiel für eine detailliertere Lösung, die leichter zu befolgen ist.
Zündkerze
0

Ich sehe dies in Angular 6, auch ohne Submit-Buttons. tritt auf, wenn mehrere Formulare in derselben Vorlage vorhanden sind. Ich bin mir nicht sicher, ob es eine Lösung gibt / was die Lösung ist.

Nir
quelle
0

Ich hatte diese Warnung, ich änderte den Schaltflächentyp "Senden" in "Schaltfläche" Problem gelöst.

Shahid Islam
quelle
0

Wenn Sie weiterhin die Funktionalität der Schaltfläche vom Typ "Senden" beibehalten möchten, sollten Sie das Klickereignis für diese Schaltfläche nicht verwenden. Verwenden Sie stattdessen das Ereignis ngSubmit im Formular.

Beispiel:

<form (ngSubmit)="destroyComponent()">
<button type="submit">submit</button>
</form>
DonDaniel
quelle
-1

Möglicherweise leiten Sie bei der Übermittlung Ihres Formulars eine andere Seite weiter. Verwenden Sie die programmatische Routennavigation wie im folgenden Beispiel, anstatt routerlinkin die Vorlage zu wechseln:

router.navigate(['/your/router/path'])

Suyash Patwardhan
quelle