Angular 2:表单提交已取消,因为表单未连接

nic*_*ick 68 html javascript forms angular angular-forms

我有一个包含表单的模态,当模态被销毁时,我在控制台中收到以下错误:

表单提交已取消,因为表单未连接

模态被添加到一个<modal-placeholder>元素中,该元素是<app-root>我的顶级元素的直接子元素.

从DOM中删除表单并在Angular 2中删除此错误的正确方法是什么?我目前正在使用componentRef.destroy();

小智 145

可能还有其他原因,但在我的情况下,我有一个按钮,由浏览器解释为提交按钮,因此单击按钮时提交表单导致错误.添加type ="button"修复了问题.完整元素:

    <button type="button" (click)="submitForm()">
Run Code Online (Sandbox Code Playgroud)

  • 我不确定为什么这个答案被接受了,因为在这样做时,你失去了按Enter键提交表单的能力. (27认同)
  • Nour的答案是最简单的答案,并允许输入密钥. (6认同)
  • 就我而言,此错误发生在“取消”按钮上,因此最好添加 `type="button"` :) (3认同)
  • 这解决了我的问题,我在表单中实现了一个CANCEL按钮,它通过*ngIf指令从页面中删除了表单.我有一个SAVE按钮触发逻辑也删除表单(成功保存)但是这个错误消息从未出现过,即使我没有type ='button'. (2认同)

Nou*_*our 64

在表单标记中,您应该编写以下内容:

 <form #myForm="ngForm" (ngSubmit)="onSubmit()">
Run Code Online (Sandbox Code Playgroud)

在表单内你应该有提交按钮:

 <button type="submit"></button>
Run Code Online (Sandbox Code Playgroud)

最重要的是,如果表单中有任何其他按钮,则应添加type="button"它们.保留默认type属性(我认为是submit)将导致警告消息.

<button type="button"></button>
Run Code Online (Sandbox Code Playgroud)

  • 我认为不需要#myForm =“ ngForm”。 (2认同)
  • 注意:确保您“不”在按钮上使用单击处理程序。就我而言,我尝试同时使用 &lt;form (ngSubmit)="onSubmit()"&gt; * 和 * &lt;button (click)="onSubmit()"&gt; ,并得到相同的错误。换句话说,如果您使用反应形式,请确保您*不*使用 Erik Lindblad 的答案。 (2认同)

小智 21

所以我实际上今天遇到了完全相同的问题,除非没有涉及模态.在我的表格中,我有两个按钮.提交表单的表单和单击表单后返回上一页的表单.

<button class="btn btn-default" routerLink="/events">Cancel</button>
<button type="submit" class="btn btn-primary">Submit</button>
Run Code Online (Sandbox Code Playgroud)

单击带有routerLink的第一个按钮完全符合它的预期,但显然也尝试提交表单,然后必须放弃表单提交,因为表单所在的页面在提交期间从DOM中卸载.

除了使用模态而不是整个页面外,这似乎与您发生的完全相同.

如果您直接将第二个按钮的类型指定为提交以外的其他类型,则问题将得到解决.

<button type="button "class="btn btn-default" routerLink="/events">Cancel</button>
Run Code Online (Sandbox Code Playgroud)

因此,如果您通过"取消"按钮或某种类型关闭模式,指定该按钮的类型(如上所示)应该可以解决您的问题.


Igo*_*bic 5

在表单元素中,您需要定义提交方法(ngSubmit),例如: <form id="currency-edit" (ngSubmit)="onSubmit(f.value)" #f="ngForm">

在提交按钮上省略了click方法,因为您的表单现在已连接到提交方法: <button class="btn btn-success" type="submit">Save</button>该按钮应为提交类型.

在代码隐藏组件中,您实现了"onSubmit"方法,例如:onSubmit(value: ICurrency) { ... } 这样的方法: 此方法接收带有表单字段值的值对象.


dhi*_*ilt 5

如果提交表单伴随着组件的销毁,表单提交将在竞争条件下失败,表单与 DOM 分离。说,我们有

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

如果saveData是异步的(例如它通过 API 调用保存数据)那么我们可以等待结果:

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

如果您需要立即放弃表格,零延迟方法也应该有效。这保证了 DOM 分离在表单提交被调用后处于下一个事件循环中:

submitForm() {
  this.saveData();
  setTimeout(() => this.abandonForm());
}
Run Code Online (Sandbox Code Playgroud)

无论按钮类型如何,这都应该有效。


小智 5

我最近遇到了这个问题并event.preventDefault()为我工作。将其添加到您的点击事件方法中。

<button type="submit" (click)="submitForm($event)" mat-raised-button>Save</button>
Run Code Online (Sandbox Code Playgroud)

和:

submitForm(event: Event) {
  event.preventDefault();
  // ...
}
Run Code Online (Sandbox Code Playgroud)

  • 这个答案没有足够的细节。请令人信服地解释这个解决方案与列出的其他解决方案有何不同或更好,因为本文已经有几个解决方案。请在发帖前阅读 SO 指南。 (2认同)
  • @sparkplug 不要把关,这个答案很有用,即使它需要更多细节。 (2认同)