Кутовий 2: Подання форми скасовано, оскільки форма не пов’язана


84

У мене є модаль, який містить форму, коли модаль знищений, я отримую таку помилку в консолі:

Подання форми скасовано, оскільки форма не пов’язана

Модаль додається до <modal-placeholder>елемента, який є прямим нащадком для <app-root>мого елемента верхнього рівня.

Який правильний спосіб видалити форму з DOM і позбутися цієї помилки в Angular 2? В даний час я використовуюcomponentRef.destroy();



у вас був * ngIf, який приховує та показує форму?
mickdev 01.03.17

@mickdev no * ngЯкщо я знищу модал так componentRef.destroy();, я додав більше деталей до свого запитання. Дякую!
нік

2
@mickdev, що мені робити, якщо я використовую * ngif, щоб приховати та показати форму
Jun711,

Відповіді:


184

Можуть існувати й інші причини, що це трапляється, але в моєму випадку у мене була кнопка, яку браузер інтерпретував як кнопку надсилання, а отже, форму було надіслано при натисканні кнопки, що спричинило помилку. Додавання type = "button" вирішило проблему. Повний елемент:

    <button type="button" (click)="submitForm()">

36
Я не впевнений, чому прийняли цю відповідь, оскільки, роблячи це, ви втрачаєте можливість натискати клавішу Enter, щоб надіслати форму.
Peter LaBanca

7
Відповідь Нура є найпростішою і дозволяє ввести ключ.
Heiner

2
Це вирішило мою проблему, коли я реалізовував кнопку CANCEL у формі, яка видаляла форму зі сторінки за допомогою директиви * ngIf. У мене є кнопка ЗБЕРЕГТИ, яка запускає логіку для видалення форми (при успішному збереженні), але це повідомлення про помилку ніколи не з'являлося разом із нею, хоча у мене немає типу = 'button'.
AlanObject

3
У моєму випадку ця помилка сталася на кнопці "Скасувати", тому добре, що я додав type="button":)
Маркос Ліма

Я думаю, що ця відповідь хороша тим, що ви повинні чітко вказати у своїх формах, яка кнопка є кнопкою подання. Це вирішує проблему неправильної кнопки, яка використовується для подання, а також дозволяє продовжувати використовувати клавішу Enter для подання.
Джастін

84

У тезі форми ви повинні написати наступне:

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

і всередині форми ви повинні мати кнопку подати:

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

І найголовніше, якщо у вас є будь-які інші кнопки у вашій формі, ви повинні type="button"до них додати . Залишення typeатрибута за замовчуванням (що, на мою думку, є submit) спричинить попереджувальне повідомлення.

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

2
Я думаю, що # myForm = "ngForm" не потрібно.
Хайнер

Ви маєте рацію, якщо вам не потрібно посилання на ngForm, це не потрібно.
Nour

Це правильний спосіб його вирішення. Це позбавляє повідомлення, зберігаючи можливість надсилання, натискаючи клавішу Enter.
Вільям Стівенс,

це повинна бути прийнята відповідь
nt4f04und

24

Тож я фактично щойно зіткнувся з точно такою ж проблемою сьогодні, за винятком випадків, коли задіяний модаль. У моїй формі у мене дві кнопки. Той, який подає форму, і той, який при натисканні повертається до попередньої сторінки.

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

Натискання на першу кнопку з routerLink робить саме те, що передбачалося, але також, очевидно, також намагається подати форму, а потім повинен відмовитись від надсилання форми, оскільки сторінка, на якій була форма, під час надсилання демонтується з DOM.

Здається, це точно те саме, що відбувається з вами, за винятком модального, а не всієї сторінки.

Проблема вирішується, якщо ви безпосередньо вказуєте тип другої кнопки як щось інше, ніж подати.

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

Отже, якщо ви закриваєте модаль за допомогою кнопки «Скасувати» або чогось подібного, вказання типу цієї кнопки, як показано вище, має вирішити вашу проблему.


6

В елементі форми потрібно визначити метод подання (ngSubmit), щось на зразок: <form id="currency-edit" (ngSubmit)="onSubmit(f.value)" #f="ngForm">

а на кнопці подати ви опускаєте метод натискання, оскільки ваша форма тепер підключена до методу подання: <button class="btn btn-success" type="submit">Save</button>Кнопка повинна мати тип подання.

У коді, що стоїть за компонентом, ви реалізуєте метод "onSubmit", наприклад приблизно так: onSubmit(value: ICurrency) { ... } Цей метод отримує об'єкт значення зі значеннями з полів форми.


Дякую, це має бути прийнятою відповіддю, якщо ви все ще хочете використовувати button type = "submit" у своїй формі
Фют,

4

У випадку, якщо подання форми супроводжується знищенням компонента, подання форми не вдається в перегоновому стані з від'єднанням форми від DOM. Скажімо, маємо

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

Якщо saveDataє асинхронним (наприклад, він зберігає дані за допомогою виклику API), то ми можемо дочекатися результату:

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

Якщо вам потрібно негайно залишити форму, також повинен спрацювати підхід з нульовою затримкою. Це гарантує, що загін DOM потрапить до наступного циклу подій після виклику подання форми:

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

Це має працювати незалежно від типу кнопки.


2

У мене була ця проблема нещодавно, і я event.preventDefault()працював у мене. Додайте його до свого методу клікової події.

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

І:

submitForm(event: Event) {
  event.preventDefault();
  // ...
}

2
Для цієї відповіді недостатньо деталей. Будь ласка, переконливо поясніть, чим це рішення відрізняється чи краще, ніж інші з перерахованих, оскільки ця публікація вже має кілька рішень. Будь ласка, прочитайте рекомендації щодо SO перед публікацією.
свічка

1
@sparkplug don't gatekeep, ця відповідь була корисною, навіть якщо потребувала деталей.
Will Shaver

Уілл Шевер - корисний, можливо. Добре відформатований і простий в інтерпретації, не так вже й багато. Існують стандарти, що забезпечують легке читання та розуміння відповідей для користувачів SO. Відповідь @dhilt - це приклад більш детального рішення, за яким легше слідувати.
свічка запалювання

0

Я бачу це в Angular 6, навіть не маючи кнопок подання взагалі. трапляється, коли в одному шаблоні є кілька форм. не впевнений, чи є рішення / яке рішення.


0

у мене було це попередження, я змінив тип кнопки "надіслати" на вирішену проблему "кнопки".


0

Якщо ви все-таки хочете зберегти функціональність кнопки типу "подати", тоді ви не повинні використовувати подію клацання на цій кнопці. Натомість вам слід використати подію ngSubmit у формі.

Приклад:

<form (ngSubmit)="destroyComponent()">
<button type="submit">submit</button>
</form>

-1

Можливо, ви переходите на якусь іншу сторінку у вашій формі подання. Використовуйте програмну навігацію маршрутом, як у наведеному нижче прикладі, а не переходячи routerlinkдо шаблону:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.