Angular 2: Przesłanie formularza zostało anulowane, ponieważ formularz nie jest połączony

84

Mam modal, który zawiera formularz, po zniszczeniu modalu pojawia się następujący błąd w konsoli:

Przesłanie formularza zostało anulowane, ponieważ formularz nie jest połączony

Modal jest dodawany do <modal-placeholder>elementu, który jest bezpośrednim dzieckiem <app-root>mojego elementu najwyższego poziomu.

Jaki jest właściwy sposób usunięcia formularza z DOM i pozbycia się tego błędu w Angular 2? Obecnie używamcomponentRef.destroy();

nacięcie
źródło
czy miałeś * ngIf, że ukryj i pokaż formularz?
mickdev
@mickdev no * ng Jeśli w ten sposób zniszczę modal componentRef.destroy();, dodałem więcej szczegółów do mojego pytania. Dzięki!
nick
2
@mickdev, co powinienem zrobić, jeśli używam * ngif do ukrycia i wyświetlenia formularza
Jun711

Odpowiedzi:

183

Mogą istnieć inne powody, dla których tak się dzieje, ale w moim przypadku miałem przycisk, który został zinterpretowany przez przeglądarkę jako przycisk przesyłania, a zatem formularz został przesłany po kliknięciu przycisku, co spowodowało błąd. Dodanie type = "button" rozwiązało problem. Pełny element:

    <button type="button" (click)="submitForm()">
Erik Lindblad
źródło
36
Nie jestem pewien, dlaczego ta odpowiedź została przyjęta, ponieważ robiąc to, tracisz możliwość naciśnięcia klawisza Enter w celu przesłania formularza.
Peter LaBanca,
7
Odpowiedź Nour jest najprostsza i umożliwia wprowadzenie klawisza Enter.
Heiner
2
To rozwiązało mój problem polegający na tym, że implementowałem przycisk ANULUJ do formularza, który usuwał formularz ze strony za pomocą dyrektywy * ngIf. Mam przycisk ZAPISZ, który uruchamia logikę, która również usuwa formularz (po pomyślnym zapisaniu), ale ten komunikat o błędzie nigdy się z nim nie pojawił, mimo że nie mam przycisku type = ''.
AlanObject
3
W moim przypadku ten błąd wystąpił na przycisku Anuluj, więc dobrze dodałem type="button":)
Marcos Lima
Myślę, że ta odpowiedź jest dobra, ponieważ w formularzach należy wyraźnie określić, który przycisk jest przyciskiem przesyłania. Rozwiązuje problem niewłaściwego przycisku używanego do przesyłania, a także umożliwia dalsze używanie klawisza Enter do przesyłania.
Justin
84

W tagu formularza należy wpisać:

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

aw formularzu powinien znajdować się przycisk przesyłania:

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

A co najważniejsze, jeśli masz jakieś inne przyciski w swoim formularzu, powinieneś type="button"je dodać . Pozostawienie domyślnego typeatrybutu (który moim zdaniem jest submit) spowoduje wyświetlenie komunikatu ostrzegawczego.

<button type="button"></button>
Nour
źródło
2
Myślę, że # myForm = "ngForm" nie jest wymagane.
Heiner
Masz rację, chyba że potrzebujesz odniesienia do ngForm, nie jest to wymagane.
Nour
To jest właściwy sposób rozwiązania tego problemu. Spowoduje to usunięcie wiadomości przy jednoczesnym zachowaniu możliwości przesłania przez naciśnięcie klawisza Enter.
William Stevens
to musi być zaakceptowana odpowiedź
nt4f04und
24

Tak więc dzisiaj właśnie natknąłem się na dokładnie ten sam problem, z wyjątkiem braku zastosowania modalu. W swojej formie mam dwa przyciski. Jeden, który przesyła formularz, i taki, który po kliknięciu kieruje z powrotem do poprzedniej strony.

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

Kliknięcie pierwszego przycisku z routerem routerLink robi dokładnie to, co powinno, ale również najwyraźniej próbuje przesłać formularz, a następnie musi porzucić przesyłanie formularza, ponieważ strona, na której był formularz, jest odłączana od DOM podczas przesyłania.

Wydaje się, że jest to dokładnie to samo, co dzieje się z tobą, z wyjątkiem tego, że zamiast całej strony pojawia się modal.

Problem zostanie rozwiązany, jeśli bezpośrednio określisz typ drugiego przycisku jako inny niż przesyłanie.

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

Więc jeśli zamykasz modal za pomocą przycisku „Anuluj” lub czegoś w tym rodzaju, określenie typu tego przycisku, jak pokazano powyżej, powinno rozwiązać problem.

Darkrender
źródło
6

W elemencie formularza należy zdefiniować metodę przesyłania (ngSubmit), na przykład: <form id="currency-edit" (ngSubmit)="onSubmit(f.value)" #f="ngForm">

a na przycisku przesyłania pomijasz metodę kliknięcia, ponieważ Twój formularz jest teraz połączony z metodą przesyłania: <button class="btn btn-success" type="submit">Save</button> Przycisk powinien być typu przesyłania.

W kodzie komponentu zaimplementowano metodę "onSubmit", na przykład coś takiego: onSubmit(value: ICurrency) { ... } Ta metoda otrzymuje obiekt wartości z wartościami z pól formularza.

Igor Babic
źródło
Dzięki, to powinna być zaakceptowana odpowiedź, jeśli nadal chcesz używać przycisku type = "submit" w swoim formularzu
Fjut
4

W przypadku, gdy przesłaniu Formularza towarzyszy zniszczenie komponentu, przesłanie Formularza nie powiedzie się w stanie wyścigowym wraz z odłączeniem Formularza od DOM. Powiedz, że mamy

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

Gdyby saveData jest async (np. Zapisuje dane poprzez wywołanie API) to możemy czekać na wynik:

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

Jeśli musisz natychmiast porzucić formularz, podejście z zerowym opóźnieniem również powinno działać. Gwarantuje to, że odłączenie DOM znajdzie się w następnej pętli zdarzeń po wywołaniu przesłania formularza:

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

Powinno to działać niezależnie od typu przycisku.

dhilt
źródło
2

Niedawno miałem ten problem i event.preventDefault()pracowałem dla mnie. Dodaj go do metody zdarzenia kliknięcia.

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

I:

submitForm(event: Event) {
  event.preventDefault();
  // ...
}
Abubakar Ibrahim
źródło
2
Ta odpowiedź nie jest wystarczająco szczegółowa. Proszę wyjaśnić przekonująco, czym to rozwiązanie różni się lub lepsze od pozostałych wymienionych, ponieważ ten post ma już kilka rozwiązań. Przeczytaj wytyczne dotyczące SO przed wysłaniem.
świeca zapłonowa
1
@sparkplug nie gatekeep, ta odpowiedź była przydatna, nawet jeśli wymagała więcej szczegółów.
Will Shaver
Will Shaver - może przydatne. Dobrze sformatowany i łatwy do zinterpretowania, nie tak bardzo. Istnieją standardy, które zapewniają, że odpowiedzi są łatwe do odczytania i zrozumienia przez użytkownika SO. Odpowiedź @dhilt jest przykładem rozwiązania bardziej szczegółowego, które jest łatwiejsze do naśladowania.
świeca zapłonowa
0

Widzę to w Angular 6, nawet bez żadnych przycisków przesyłania. dzieje się, gdy w tym samym szablonie znajduje się wiele formularzy. nie jestem pewien, czy istnieje rozwiązanie / jakie jest rozwiązanie.

Nir
źródło
0

otrzymałem to ostrzeżenie, zmieniłem typ przycisku „wyślij” na „przycisk” rozwiązany problem.

Shahid Islam
źródło
0

Jeśli nadal chcesz zachować funkcjonalność przycisku typu „wyślij”, nie powinieneś używać zdarzenia kliknięcia na tym przycisku. Zamiast tego w formularzu należy użyć zdarzenia ngSubmit.

Przykład:

<form (ngSubmit)="destroyComponent()">
<button type="submit">submit</button>
</form>
DonDaniel
źródło
-1

Być może kierujesz do innej strony w przesłanym formularzu. Korzystaj z programowej nawigacji po trasach, jak w poniższym przykładzie, zamiast przechodzić routerlinkdo szablonu:

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

suyash patwardhan
źródło