提交表单状态防止

Posted

技术标签:

【中文标题】提交表单状态防止【英文标题】:Submitted form state preventing 【发布时间】:2017-03-07 18:51:54 【问题描述】:

如何在提交表单时避免在表单中提交状态(以及ng-submitted 类和提交范围属性为真布尔值)?

更新

( function() 
angular
  .module( 'app', [] )
  .controller( 'SubmitController', SubmitController );

function SubmitController() 
  var vm = this;
  vm.submit = submit;

  function submit( e ) 
    console.log( 'Submit!' );
    e.stopPropagation();
  

 )();
form,
[ng-form] 
  padding: 1em;
  border: 1px solid black;


.ng-submitted 
  border: 1px solid red;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>

<div ng-app="app">
  <div ng-controller="SubmitController as vm">
    <div ng-form>
      <form novalidate ng-submit="vm.submit($event)">
        <input type="text">
        <button type="submit">Submit</button>
      </form>
    </div>
  </div>
</div>

主要目标是提交事件未触发且未到达父元素 ([ng-form])。

【问题讨论】:

As I said in GitHub, here 是关于它的 CodePen 示例。 “为什么提交会传播给父母而不是阻止?”。 所以您希望不提交子表单和父表单,还是只提交其中一个? 至少,父级停止传播。 我不清楚你在问什么,甚至四个人都回答了。 一种防止和停止提交事件传播的机制。 【参考方案1】:

防止表单提交的简单方法,使用您的 Angular 代码添加这种类型的逻辑条件:

<form name="formName" novalidate ng-submit="formName.$valid && ANY_LOGIC_CONDITION_LIKE_LOGIN.submit()">

这将有助于防止表单提交

【讨论】:

我真的想在被调用的函数中阻止,而不是依赖于表单的有效状态。请查看添加的实时代码。【参考方案2】:

看到这个。 使用formName.$valid 阻止提交表单并在您的文本框中添加ng-model

( function() 
angular.module( 'app', [] )
	.controller( 'FormsController', FormsController );

function FormsController() 
  
	var vm = this;
	vm.submit = submit;
	
	function submit( e ) 
		console.log( 'Submit!' );
		e.preventDefault();
		e.stopPropagation();
	

 )();
[ng-form],
form 
  padding: 10px;
  border: 1px solid #000;
  &.ng-submitted 
    border: 1px solid #f00;
  
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
	<div ng-controller="FormsController as vm">
    <div ng-form>
      <form name="test" novalidate name="test" ng-submit="test.$valid && vm.submit($event)">
        <input type="text" ng-model="vm.test" required>
        <button type="submit">Submit</button>
      </form>
    </div>
  </div>
</div>

【讨论】:

As I said to Kamal Kumar,我不想依赖有效状态。 并且注意CSS代码确实是Less/Sass并且使用了不必要的preventDefault方法,因为你使用了古老的代码。查看更新后的问题。【参考方案3】:

添加指令后,请参阅 @Taylor Buchanan 的回答 here。你可以简单地从你的 javascript 函数中调用它。

你必须做什么:

    将该指令添加到您的代码中。 为您的父表单添加一个名称:ng-form="myForm"。 将您的表单传递给您的提交函数:`vm.submit(myForm)'。

    然后修改你的函数:

    函数提交(表单) console.log('提交!'); form.$setUnsubmitted();

附:由于我不确定您要取消提交哪一种表格,所以我假设您两者都想要。但是很明显,你得到了完全的控制,所以你可以相应地修改代码。

【讨论】:

The Bear has already proposed this.【参考方案4】:

更新

看到你的代码/行为(更新后)...... 为什么必须提交子表单? 有什么好处?我看到您使用的是novalidate,所以浏览器验证不起作用。 为什么你不简单地使用ng-click="vm.click(myForm)"。使用父表单不会有任何问题,并且 angularjs 不会添加/设置任何$submitted 状态或ng-selected 类,因此您可以在传递简单表单实例时手动处理。

PLUNKER DEMO

HTML

<div ng-form>
  <form id="myForm" name="myForm" novalidate >
    <label>My Input:</label>
    <input type="text" name="myInput" ng-model="vm.item.myInput" required>
    <button type="button" ng-click="vm.click(myForm)">Submit</button>
  </form>
</div>

控制器/JS

app.controller('MainCtrl', function($scope) 
    vm.click = function (myForm) 
        alert('submitted');
        //myForm.$valid
        //call to server 
    
);

如果这种方式适合您的场景,那么您就是一个遮阳篷...如果不适合,我希望其他一些解决方案适合您:)

【讨论】:

我知道一个类似的解决方案,但它不是搜索的。请查看问题并查看添加的实时代码。 关于更新:主要目标是停止提交事件的传播,该事件仅用于检测用户提交按钮确认。【参考方案5】:

可以触发FormController的$setPristine()方法。您只需要将表单本身作为参数传递给您的提交函数并触发其内置方法。

例如

查看

<form name="MyForm" ng-submit="submitForm(MyForm)">
    <button type="submit">Submit</button>
</form> 

控制器

$scope.submitForm = (form) => 
  form.$setPristine();
  alert("Form was submitted")

Here's a working example of the above code snippet.

更新

如果你有嵌套的表单并不重要。传播不像你想象的那样工作。您还应该为您的ng-form 命名。然后将其传递给提交函数并再次调用其内置的$setPristine() 方法。

检查这个代码块:

查看:

<div ng-form name="outterForm">
  <form name="myForm" ng-submit="vm.submit($event,myForm, outterForm)">
      <button type="submit">Submit</button>
  </form>
</div>

控制器:

function submit( e, form1, form2 ) 
    console.log( 'Submit!' );
    e.stopPropagation();
    form1.$setPristine();
    form2.$setPristine();
  

Here's an the updated example based on your code chunk demonstrating the nested forms case.

【讨论】:

很明显,重复代码是可能的。从逻辑上讲,这不是一个好的解决方案。 你是对的,但恐怕没有其他解决方法。传播不是那样工作的。 正因为如此,我的问题。谢谢。

以上是关于提交表单状态防止的主要内容,如果未能解决你的问题,请参考以下文章

防止表单重复提交

防止使用 angular.js 提交多个表单 - 禁用表单按钮

HTTP 的幂等性 分析 POST 表单重复提交

防止表单重复提交

如何在表单提交时防止表单在刷新时重新提交

php 如何防止表单重复提交呢