222

我在 Angular 中有一个表单,其中有两个按钮标签。一键提交表单ng-click。另一个按钮纯粹用于使用 导航ng-click。但是,当单击第二个按钮时,AngularJS 会导致页面刷新,从而触发 404。我在函数中放置了一个断点,它正在触发我的函数。如果我执行以下任何操作,它将停止:

  1. 如果我删除ng-click,该按钮不会导致页面刷新。
  2. 如果我注释掉函数中的代码,它不会导致页面刷新。
  3. 如果我将按钮标签更改为带有 的锚标签 ( <a>) href="",则不会导致刷新。

后者似乎是最简单的解决方法,但为什么 AngularJS 甚至在我的函数之后运行任何导致页面重新加载的代码?似乎是一个错误。

这是表格:

<form class="form-horizontal" name="myProfile" ng-switch-when="profile">
  <fieldset>
    <div class="control-group">
      <label class="control-label" for="passwordButton">Password</label>
      <div class="controls">
        <button id="passwordButton" class="secondaryButton" ng-click="showChangePassword()">Change</button>
      </div>
    </div>

    <div class="buttonBar">
      <button id="saveProfileButton" class="primaryButton" ng-click="saveUser()">Save</button>
    </div>
  </fieldset>
</form>

这是控制器方法:

$scope.showChangePassword = function() {
  $scope.selectedLink = "changePassword";
};
4

11 回答 11

490

如果您查看W3C 规范,似乎显而易见的尝试是type='button'在您不希望它们提交时标记您的按钮元素。

特别要注意的是它说的地方

未指定类型属性的按钮元素与类型属性设置为“提交”的按钮元素表示相同的事物

于 2013-03-09T18:12:05.483 回答
73

您可以尝试阻止默认处理程序:

html:

<button ng-click="saveUser($event)">

js:

$scope.saveUser = function (event) {
  event.preventDefault();
  // your code
}
于 2012-09-10T16:02:51.000 回答
19

ng-submit={expression}您应该在<form>标签中声明该属性。

来自 ngSubmit 文档 http://docs.angularjs.org/api/ng.directive:ngSubmit

启用绑定角度表达式以提交事件。

此外,它会阻止默认操作(对于表单而言,这意味着将请求发送到服务器并重新加载当前页面)。

于 2012-09-07T20:08:14.527 回答
18

我使用指令来防止默认行为:

module.directive('preventDefault', function() {
    return function(scope, element, attrs) {
        angular.element(element).bind('click', function(event) {
            event.preventDefault();
            event.stopPropagation();
        });
    }
});

然后,在 html 中:

<button class="secondaryButton" prevent-default>Secondary action</button>

该指令也可以与<a>所有其他标签一起使用

于 2014-02-05T12:50:23.760 回答
5

可以保留<button type="submit">,但必须去掉 的属性action=""<form>

于 2016-02-07T06:25:49.893 回答
2

我想知道为什么没有人提出可能最简单的解决方案:

不要使用<form>

恕我直言, A<whatever ng-form>做得更好,并且没有 HTML 表单,浏览器本身无需提交任何内容。使用角度时,这完全是正确的行为。

于 2016-03-23T00:03:53.167 回答
1

这个答案可能与问题没有直接关系。这仅适用于您使用脚本提交表单的情况。

根据ng-submit 代码

 var handleFormSubmission = function(event) {
  scope.$apply(function() {
    controller.$commitViewValue();
    controller.$setSubmitted();
  });

  event.preventDefault();
};

formElement[0].addEventListener('submit', handleFormSubmission);

它在表单上添加了提交事件侦听器。但是通过调用 form.submit() 发起提交时,不会调用提交事件处理程序。在这种情况下,ng-submit 不会阻止默认操作,您必须自己在 ng-submit 处理程序中调用 preventDefault;

为了提供一个合理确定的答案,HTML 表单提交算法第 5 项指出,如果表单没有通过调用 submit 方法提交,它只会调度提交事件(这意味着如果通过按钮或其他隐式提交,它只会调度提交事件方法,例如在焦点位于输入类型文本元素上时按 Enter)。

请参阅使用 submit() 从链接提交的表单不能被 onsubmit 处理程序捕获

于 2017-12-09T12:04:12.977 回答
1

向您的表单添加操作。

<form action="#">

于 2017-05-24T19:15:04.770 回答
0

第一个按钮提交表单,第二个不提交

<body>
<form  ng-app="myApp" ng-controller="myCtrl" ng-submit="Sub()">
<div>
S:<input type="text" ng-model="v"><br>
<br>
<button>Submit</button>
//Dont Submit
<button type='button' ng-click="Dont()">Dont Submit</button>
</div>
</form>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.Sub=function()
{
alert('Inside Submit');
}

$scope.Dont=function()
{
$scope.v=0;
}
});
</script>

</body>
于 2015-07-02T09:13:24.257 回答
0

我也遇到了同样的问题,但很高兴我通过将类型更改为 from type="submit"to 来解决这个问题,type="button"并且它起作用了。

于 2020-07-13T15:09:28.440 回答
0

只需FormsModule在文件imports数组中添加,然后在该文件的顶部添加...这将起作用。app.module.tsimport { FormsModule } from '@angular/forms';

于 2020-04-12T08:34:47.143 回答