角度2:由于未连接表单,因此取消了表单提交


82

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

由于未连接表单,因此取消了表单提交

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

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



您有一个* ngIf可以隐藏并显示表格吗?
mickdev '17

@mickdev no * ng如果我破坏了这种模态componentRef.destroy();,我在问题中添加了更多细节。谢谢!
尼克

2
@mickdev如果使用* ngif隐藏和显示该表格
怎么办

Answers:


179

可能有其他原因导致这种情况,但是在我的情况下,我有一个按钮,浏览器将其解释为“提交”按钮,因此单击该按钮时导致错误,因此提交了表单。添加type =“ button”解决了该问题。完整元素:

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

33
我不确定为什么会接受此答案,因为这样做会失去按Enter提交表格的能力。
Peter LaBanca '17

7
Nour的答案是最简单的答案,并且允许输入密钥。
Heiner

2
这解决了我在将CANCEL按钮实现到表单时通过* ngIf指令从页面中删除该表单的问题。我有一个SAVE按钮,它触发逻辑也可以删除表单(成功保存后),但是即使我没有type ='button',也从未出现此错误消息。
AlanObject '18年

3
就我而言,此错误是在“取消”按钮上发生的,所以很好地添加了type="button":)
Marcos Lima

我认为这个答案很好,因为您应该在表单中明确指出哪个按钮是“提交”按钮。它解决了提交按钮使用错误的问题,并允许您继续使用Enter键进行提交。
贾斯汀

80

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

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

在表单中,您应该具有“提交”按钮:

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

最重要的是,如果表单中还有其他按钮,则应添加type="button"到它们中。保留默认type属性(我认为是submit)会引起警告消息。

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

2
我认为不需要#myForm =“ ngForm”。
Heiner

没错,除非不需要引用ngForm,否则不需要。
诺尔

这是解决它的正确方法。这消除了消息,同时保持了按Enter提交的功能。
威廉·史蒂文斯

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

在form元素中,您需要定义Submit方法(ngSubmit),类似于: <form id="currency-edit" (ngSubmit)="onSubmit(f.value)" #f="ngForm">

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

在组件背后的代码中,您将实现“ onSubmit”方法,例如,如下所示: onSubmit(value: ICurrency) { ... } 该方法从表单字段接收带有值的值对象。


谢谢,如果您仍然想在表单上使用按钮type =“ submit”,这应该是可接受的答案
Fjut

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
  );
}

如果您需要立即放弃表格,则零延迟方法也应该可行。这样可以确保在调用Form提交后,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准则。
sparkplug '18

1
@sparkplug不要把关,这个答案很有用,即使它需要更多细节。
Will Shaver

Will Shaver-有用。格式正确且易于解释,不是很多。制定了标准,以确保SO用户易于阅读和理解答案。@dhilt的答案是更详细的解决方案示例,更易于遵循。
sparkplug

0

我什至在Angular 6中都没有看到任何提交按钮。同一模板中有多个表单时发生。不知道是否有解决方案/解决方案是什么。



0

如果您仍希望将按钮的功能保持为“提交”类型,则不应在该按钮上使用click事件。相反,您应该在表单上使用ngSubmit事件。

例:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.