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

Clicking a button within a form causes page refresh

本文关键字:刷新 表单 按钮 单击      更新时间:2023-09-26

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

如果你看过W3C规范,那么当你不想提交按钮元素时,最明显的尝试就是用type='button'标记它们。

需要特别注意的是,上面写着

没有指定类型属性的按钮元素与类型属性设置为"提交"的按钮元素表示相同的东西

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

html:

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

js:

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

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

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

启用将角度表达式绑定到取消提交事件。

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

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

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>和所有其他标签

一起使用

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

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

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

不要使用<form>

<whatever ng-form>为IMHO做得更好,如果没有HTML表单,浏览器本身就无法提交任何内容。这正是使用angular时的正确行为。

将操作添加到表单中。

<form action="#">

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

根据ng提交代码

 var handleFormSubmission = function(event) {
  scope.$apply(function() {
    controller.$commitViewValue();
    controller.$setSubmitted();
  });
  event.preventDefault();
};
formElement[0].addEventListener('submit', handleFormSubmission);

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

为了提供一个合理明确的答案,HTML表单提交算法项目5规定,如果表单不是通过调用提交方法提交的,则表单仅发送提交事件(这意味着它仅在通过按钮或其他隐式方法提交的情况下发送提交事件,例如,当焦点在输入类型文本元素上时按下回车键)。

请参阅使用submit()从链接提交的表单。onsubmit处理程序无法捕获该表单

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

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

只需在app.module.ts文件的imports数组中添加FormsModule,并在该文件的顶部添加CCD_ 21。。。这会奏效的。