避免 Angular2 在单击按钮时系统地提交表单

Posted

技术标签:

【中文标题】避免 Angular2 在单击按钮时系统地提交表单【英文标题】:Avoid Angular2 to systematically submit form on button click 【发布时间】:2016-12-11 17:41:22 【问题描述】:

好吧,也许这还不清楚。获取此表格:

<form (ngSubmit)="submit()" #crisisForm="ngForm">
   <input type="text" name="name" [(ngModel)]="crisis.name">
   <button type="submit">Submit</button>
   <button type="button" (click)="preview()">Preview</button>
   <button type="reset" (click)="reset()">Reset</button>
</form>

为什么所有按钮都会触发submit()函数?以及如何避免这种情况?

【问题讨论】:

返回假;从您的 submit() 函数 【参考方案1】:

我看到了两种解决方法:

1) 明确指定 type="button"(我认为它更可取):

<button type="button" (click)="preview();">Preview</button>

根据 W3 规范:

http://w3c.github.io/html-reference/button.html

带有的按钮元素 无类型属性 指定表示与按钮相同的东西 type 属性设置为“submit”的元素

2) 使用$event.preventDefault():

<button (click)="preview(); $event.preventDefault()">Preview</button>

<button (click)="preview($event);">Preview</button>

preview(e)
  e.preventDefault();
  console.log('preview')

【讨论】:

(click)="preview(); false" 也应该这样做。例如,stopPropagation() 需要显式调用,但如果事件处理程序返回 false,则在该事件上调用 preventDefault @Günter Zöchbauer 非常感谢您指出这一点!首先我尝试过,但我写了return false,但它没有用:) return 在绑定表达式中可能是不允许的,但最后一个表达式的值是隐式返回的。 使用#2 似乎是最好的答案。只需将: type="button" 添加到我的按钮即可解决问题 我不知道type=button W3C 的规范。谢谢!!【参考方案2】:

This Plunker 建议否则,每个按钮似乎都按预期工作。

但是,为了防止表单的默认行为,您可以这样做,


TS:

submit(e)
 e.preventDefault();

模板:

<form (submit)="submit($event)" #crisisForm="ngForm">

【讨论】:

感谢您的回答和 plnkr... 这都是关于按钮类型 plnkr.co/edit/BKIqcz7aKBFQDZioZ5Fy 确实!它是。并且您已经定义了所有按钮,因此它按预期工作【参考方案3】:

您必须从 app.module.ts 中的“@angular/forms”导入 FormsModule

import  FormsModule  from '@angular/forms';
 @NgModule(
  imports: [
    FormsModule
 ],
 )

【讨论】:

这是正确的答案,所有其他的都是 hacky non angular like uneded workarounds。【参考方案4】:

我发现在 2.0 版本中 (ngSubmit) 正在将 null 事件值传递给方法,因此您应该使用 (submit)

<form (submit)="submit($event)" #crisisForm="ngForm">

你的 .ts 文件

submit($event)
   /* form code */
   $event.preventDefault();

【讨论】:

谢谢!这行得通,不知道为什么 ngSubmit 在不用作表单组时有效,但是当我将其用作表单组时,我必须使用您的解决方案 我在 2.0 刚刚发布的时候给出了这个答案,但是在那之后 angular 2 已经走了很长一段路,所以你确定你使用的是最新版本吗?【参考方案5】:

在您不想执行提交的按钮中设置type="button"

【讨论】:

这在感觉上不是一个好主意。【参考方案6】:

我也有同样的问题。我发现的解决方法是将button 替换为a 并将按钮样式应用于锚元素:

<form (ngSubmit)="submit()" #crisisForm="ngForm">
   <input type="text" name="name" [(ngModel)]="crisis.name">
   <button type="submit">Submit</button>
   <a class="btn" (click)="preview()">Preview</a>
   <a class="btn" (click)="reset()">Reset</a>
</form>

【讨论】:

【参考方案7】:

Angular 为此提供了一个内置的解决方案。您只需将(submit)="handleSubmit()" 替换为(ngSubmit)="handleSubmit()"。通过这样做 e.preventDefault() 将被 angular 本身隐式调用。

【讨论】:

以上是关于避免 Angular2 在单击按钮时系统地提交表单的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2 提交时触发表单验证

提交表单上的阻止按钮

Semantic-UI 避免某些按钮单击事件的表单验证触发

Ajax 表单提交在第一次提交时返回错误,但在第二次单击时提交

如何正确地将单击按钮属性值传递给表单提交事件?

Angular 2 - 浏览器自动填充时表单无效