单击表单中的按钮会导致页面刷新
Posted
技术标签:
【中文标题】单击表单中的按钮会导致页面刷新【英文标题】:Clicking a button within a form causes page refresh 【发布时间】:2012-09-01 10:26:14 【问题描述】:我在 Angular 中有一个表单,里面有两个按钮标签。一键在ng-click
上提交表单。另一个按钮纯粹用于使用ng-click
进行导航。但是,当单击第二个按钮时,AngularJS 会导致页面刷新,从而触发 404。我在函数中放置了一个断点,它正在触发我的函数。如果我执行以下任何操作,它就会停止:
-
如果我删除
ng-click
,该按钮不会导致页面刷新。
如果我注释掉函数中的代码,它不会导致页面刷新。
如果我使用href=""
将按钮标签更改为锚标签(<a>
),则不会导致刷新。
后者似乎是最简单的解决方法,但为什么 AngularJS 甚至在我的函数之后运行任何导致页面重新加载的代码?好像是个bug。
这是表格:
<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 版本中)。 我看到了那个,但我没有更改位置,所以我认为它不适用。除非这个其他按钮以某种方式导致它提交,但它没有定义为提交类型,并且当我取消 ng-click 时,该按钮不会提交表单。 如果你能提供这个问题的工作演示,那就太好了。也许从:Angular Plnkr 欺骗***.com/questions/932653/… 好像是重复的。 ***.com/questions/16703215/… 【参考方案1】:如果您查看W3C specification,似乎显而易见的做法是在您不想提交按钮元素时用type='button'
标记它们。
特别要注意的是它说的地方
未指定类型属性的按钮元素与类型属性设置为“提交”的按钮元素表示相同的东西
【讨论】:
我遇到了与 OP 相同的问题,但我的按钮具有指定的类型 - 仍然单击会导致刷新。还有其他我可以看的地方吗? 这向我表明您的问题出在 javascript 中。我的回答要解决的问题更多是 dom 和浏览器之间的问题。一些处理您的按钮单击的 javascript 可能会导致您看到重新加载。狩猎快乐;) 这正是我想要的。我的页面很烦人,因为它应该只显示错误而不提交。 我的按钮标有 type="button" 并且也有问题。在我的 ng-click 处理程序中,我有 $event.stopPropagation()。当我删除它时,它不会重新加载。不过我需要它。任何想法为什么会导致页面重新加载?! @freshfelicio:尝试同时添加$event.preventDefault()
,这对我的情况有所帮助。但我没有解释为什么:-\【参考方案2】:
您可以尝试阻止默认处理程序:
html:
<button ng-click="saveUser($event)">
js:
$scope.saveUser = function (event)
event.preventDefault();
// your code
【讨论】:
不错!它真的很适合我的场景! 这对我们有用,在 SharePoint 表单中使用 AngularJS 时。我确实必须添加“event.stopPropagation();”不过也一样。【参考方案3】:您应该在<form>
标签中声明属性ng-submit=expression
。
来自 ngSubmit 文档 http://docs.angularjs.org/api/ng.directive:ngSubmit
启用将角度表达式绑定到 onsubmit 事件。
此外,它会阻止默认操作(对于表单而言,这意味着将请求发送到服务器并重新加载当前页面)。
【讨论】:
另外,请确保您没有在表单上设置 'action' 属性:form(action="/login", lng-submit="login()") 因为这会使页面刷新即使您设置了 ng-submit。 提交表单并阻止默认操作 由于表单在客户端 Angular 应用程序中的作用与经典往返应用程序不同,因此浏览器最好不要将表单提交转换为整页reload 将数据发送到服务器。相反,应该触发一些 javascript 逻辑来以应用程序特定的方式处理表单提交。出于这个原因,除非 我有一个带有 ng-submit=expression 的表单和一个带有 type="submit" 的按钮。除了在 BB10 上外,工作正常。如果我使用 BB10 键盘的提交,那么页面将刷新。如果我使用我在表单中声明的按钮,它可以正常工作。 这对我不起作用。我完全按照指示进行。该页面仍在回发【参考方案4】:我使用指令来防止默认行为:
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
指令时,这很有帮助。
谢谢你,但我还需要取消指令中的 ng-click
这样也可以防止表单触发 ng-submit 回调,对吧?【参考方案5】:
您可以保留<button type="submit">
,但必须删除<form>
的属性action=""
。
【讨论】:
【参考方案6】:我想知道为什么没有人提出可能最简单的解决方案:
不要使用
<form>
<whatever ng-form>
恕我直言做得更好,并且没有 HTML 表单,浏览器本身无需提交任何内容。使用角度时,这正是正确的行为。
【讨论】:
如何在没有表单标签的情况下强制点击表单有效? @RizwanPatel 我猜,我不明白,但是使用ng-form=someForm
,你会得到$scope.someForm
,它有一个$valid
字段。所以我通过<button ng-disabled="!someForm.$valid">
得到了我需要的一切。【参考方案7】:
向您的表单添加操作。
<form action="#">
【讨论】:
【参考方案8】:此答案可能与问题没有直接关系。仅适用于使用脚本提交表单的情况。
根据ng-submit code
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)。
见Form submitted using submit() from a link cannot be caught by onsubmit handler
【讨论】:
【参考方案9】:第一个按钮提交表单,第二个不提交
<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>
【讨论】:
【参考方案10】:只需在app.module.ts
文件的imports
数组中添加FormsModule
,
并在这个文件的顶部添加import FormsModule from '@angular/forms';
...这样就可以了。
【讨论】:
【参考方案11】:我也遇到了同样的问题,但很高兴我通过将类型从 type="submit"
更改为 type="button"
来解决此问题,并且成功了。
【讨论】:
以上是关于单击表单中的按钮会导致页面刷新的主要内容,如果未能解决你的问题,请参考以下文章