Кутовий 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.