2012-09-07 103 views
187

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

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

后者似乎是最简单的解决方法,但为什么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"; 
}; 
+0

看看这是你的问题https://github.com/angular/angular.js/issues/1238 (不幸的是,我不知道我身边的github的方式足以被能够判断这个修复是否在1.0.1版本中)。 –

+0

我看到一个,但我没有改变位置,所以我不认为它适用。除非这个按钮以某种方式导致它提交,但它没有被定义为提交类型,并且当我脱离ng-click时,按钮不会提交表单。 – chubbsondubs

+0

这将是伟大的,你可以提供这个问题的工作演示。也许从以下开始:[Angular Plnkr](http://plnkr.co/edit/gist:3662656) –

回答

399

如果你看看W3C specification,它会像要尝试的最明显的事情就是当你不想要的时候用type='button'来标记你的按钮元素m提交。

特别要注意的一点是,它说

没有指定类型属性的按钮元素表示同样的事情,有其type属性设置一个按钮元素“提交”

+4

我与OP有同样的问题,但我的按钮具有指定类型 - 仍然单击会导致刷新。任何其他我可以看的地方? –

+0

这表明你的问题在JavaScript中。我的答案正在解决的问题更多地是dom和浏览器之间的问题。处理按钮点击的一些JavaScript可能会导致您看到的重新加载。快乐狩猎;) – LOAS

+0

这正是我一直在寻找的。这在我的网页上非常讨厌,因为它应该只显示错误而不提交。 –

18

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

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

启用结合角表达式的onsubmit事件。

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

+3

此外,请确保您没有在窗体上设置'action'属性:form(action =“/ login”,lng-submit =“login()”) 因为这会使页面刷新,即使您有ng - 提交集。 – jenso

+0

提交表单并阻止默认操作 由于客户端Angular应用程序中的表单角色与传统往返应用程序中的角色不同,因此浏览器不希望将表单提交转换为发送数据的完整页面重新加载到服务器。相反,应该触发一些JavaScript逻辑来以应用程序特定的方式处理表单提交。 因此,除非

元素具有指定的操作属性,否则Angular会阻止默认操作(将表单提交到服务器)。 - http://docs.angularjs.org/api/ng.directive:form –

+0

我有一个ng-submit = {expression}的表单和一个type =“submit”的按钮。除了在BB10上工作就好了。如果我使用BB10键盘的提交,则页面将刷新。如果我使用我在窗体中声明的按钮,它可以正常工作。 – Michael

67

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

HTML:

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

JS:

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

不错!它真的取材于我的场景! – Richard

+2

在SharePoint表单中使用AngularJS时,这对我们有效。我不得不添加“event.stopPropagation();”尽管如此。 –

15

我使用的指令,以防止默认行为:

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>使用和所有其它的标签

+0

+1谢谢!当你不能访问''标签时,这很有用,因此不能使用'ng-submit'指令。 – jackvsworld

+0

非常感谢这个,但我还需要取消ng-click中的指令 –

+0

这也可以防止表单触发ng-submit回调,对不对? –

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> 
4

你可以保持<button type="submit">,但必须删除的属性action=""<form>

2

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

不使用<form>

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

+0

如何在没有表单标签的情况下强制执行formvalid? –

+1

@RizwanPatel我想,我不明白,但是用'ng-form = someForm',你得到'$ scope.someForm',它有一个'$ valid'字段。所以我用'

0

将动作添加到您的表单中。

<form action="#">

0

这个答案可能并不直接相关的问题。只有在您使用脚本提交表单时才适用。

根据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条规定,形式仅调度通过调用提交方法(这意味着它仅调度提交事件,如果提交如果没有提交一个提交事件通过按钮或其他隐式方法,例如在焦点位于输入类型文本元素上时按下Enter键)。

Form submitted using submit() from a link cannot be caught by onsubmit handler