单击表单中的按钮会导致页面刷新


217

我在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";
};

看看这是否是您的问题github.com/angular/angular.js/issues/1238(不幸的是,我对github的了解不够,无法判断此修补程序是否在1.0.1版本中) 。
Mark Rajcok 2012年

我看到了那个,但是我没有改变位置,所以我认为它不适用。除非此其他按钮以某种方式导致其提交,但未将其定义为提交类型,并且当我脱下ng键时,该按钮不会提交表单。
chubbsondubs 2012年

您可以提供此问题的工作演示,将非常好。也许开始于:Angular Plnkr
Pete BD


Answers:


471

如果您查看W3C规范,似乎很容易尝试做的事情是在type='button'不想提交按钮元素时标记它们。

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

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


4
我有与OP相同的问题,但是我的按钮具有指定的类型-仍然单击会导致刷新。我还能看其他地方吗?
Mateo Velenik,2015年

这向我暗示您的问题出在javascript中。我的回答是解决的问题更多是dom和浏览器之间的问题。一些处理您的按钮单击的JavaScript可能会导致您看到重新加载。狩猎愉快;)
LOAS

这正是我想要的。我的页面上非常令人讨厌,因为它应该只显示错误而不提交。
reaper_unique 2015年

我的按钮标有type =“ button”,并且也有问题。在我的ng-click处理程序中,我有$ event.stopPropagation()。当我删除它时,它不会重新加载。不过我需要 任何想法为什么会导致页面重新加载?
felixfbecker 2015年

@freshfelicio:也尝试添加$event.preventDefault(),这对我来说很有帮助。但我没有任何解释为什么:-\
蒂姆·布斯(TimBüthe)2015年

72

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

的HTML:

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

js:

$scope.saveUser = function (event) {
  event.preventDefault();
  // your code
}

真好!这真的很符合我的情况!
理查德

2
在SharePoint表单中使用AngularJS时,这对我们有用。我确实必须添加“ event.stopPropagation();” 以及。
尼克·德梅奥

19

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

从ngSubmit docs http://docs.angularjs.org/api/ng.directive:ngSubmit

使绑定角度表达式绑定到onsubmit事件。

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


3
另外,请确保没有在以下表单上设置“ action”属性:form(action =“ / login”,lng-submit =“ login()”)因为即使您设置了ng-submit,这也会刷新页面。
jenso

提交表单并防止默认操作由于表单在客户端Angular应用程序中的作用与传统的往返应用程序不同,因此浏览器最好不要将表单提交转换为将数据发送到服务器的整页重新加载。相反,应触发一些javascript逻辑,以使用特定于应用程序的方式处理表单提交。因此,除非<form>元素指定了action属性,否则Angular会阻止默认操作(将表单提交到服务器)。- docs.angularjs.org/api/ng.directive:form
Jignesh Gohel

我有一个带有ng-submit = {expression}的表单和一个带有type =“ submit”的按钮。除了在BB10上运行外,其他都可以正常工作。如果我使用BB10键盘的Submit(提交),则页面将刷新。如果我使用在表单中声明的​​按钮,则可以正常工作。
迈克尔

这对我不起作用。我完全按照指示进行。该页面仍回发
meffect 2015年

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>和所有其他标签一起使用


+1谢谢!当您无权访问<form>标记并因此无法使用ng-submit指令时,这将很有帮助。
jackvsworld

非常感谢,但是我还需要取消指令中的ng-click
boi_echos 2015年

这也可以防止表单触发ng-submit回调,对吗?
Jhourlad Estrella 2015年


2

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

不要使用 <form>

一个<whatever ng-form>不恕我直言一个更好的工作,并没有一个HTML表单,没有什么用浏览器本身提交。使用angular时,这正是正确的行为。


如何在没有表单标签的情况下单击以强制执行formvalid?
Rizwan Patel

1
@RizwanPatel我想我不明白,但是有了ng-form=someForm,您就会知道$scope.someForm它有一个$valid字段。所以我得到了我需要的一切<button ng-disabled="!someForm.$valid">
maaartinus '16


1

该答案可能与问题不直接相关。这仅适用于使用脚本提交表单的情况。

根据ng提交代码

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

  event.preventDefault();
};

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

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

为了提供合理的确定性答案,HTML表单提交算法项目5指出,如果表单不是通过调用Submit方法提交的,则表单仅调度提交事件(这意味着仅通过按钮或其他隐式提交的表单才调度提交事件。方法,例如在焦点位于输入类型文本元素上时按Enter。

请参阅onsubmit处理程序无法捕获使用链接中的commit()提交的表单


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>

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.