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

Tho*_*mel 13 javascript form-submit angularjs angularjs-directive

我想使用angular.js阻止多个表单提交.这个问题与这个问题有关.

当用户点击表单提交按钮时,提交按钮的值/标签应更改为"正在加载...",按钮的状态将设置为禁用,并且应以正常方式触发提交事件,从而导致提交对服务器的调用.这样用户会看到以下效果:

  1. 立即:提交按钮值更改为"正在加载..."并被禁用

  2. 一旦服务器响应:用户获得服务器请求的结果(而服务器响应在没有角度干预的情况下处理)

我创建了这个插件以显示我的意思.我的问题与这一行有关:elm.attr('disabled',true);.这不仅会禁用该按钮,还会阻止传播提交事件.因此,我得到一个禁用按钮(所需的结果),但表单没有被提交(不希望的结果).

如果您评论/取消注释此行,您可以看到更改的行为: elm.attr('disabled',true);

知道怎么改变这个吗?

Mat*_*rne 21

我有一个标准的表单,只是在前端使用angular,所以如果你只需要防止在服务器响应时点击两次按钮,那么你可以使用这个可重复使用的简单指令,不需要控制器或ngModel .

http://plnkr.co/edit/2aZWQSLS8s6EhO5rKnRh?p=preview

app.directive('clickOnce', function($timeout) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var replacementText = attrs.clickOnce;

            element.bind('click', function() {
                $timeout(function() {
                    if (replacementText) {
                        element.html(replacementText);
                    }
                    element.attr('disabled', true);
                }, 0);
            });
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

它将禁用该按钮并可选择更改按钮的文本.使用如下:

<button click-once>Button just disables</button>
<button click-once="Loading...">Text changes and button disables</button>
Run Code Online (Sandbox Code Playgroud)

在目前的形式中,这只有在您进行标准表单提交而不是ajax提交时才有效.


Rud*_*udy 15

只需在控制器中添加一个新属性即可

$scope.processing = false;
Run Code Online (Sandbox Code Playgroud)

在你的方法

$scope.processData = function(){
    $scope.processing = true;
    $http.post('').then(function(){
        $scope.processing = false;
    });
});
Run Code Online (Sandbox Code Playgroud)

在你的html bind ng-disabled属性中,$ scope.processing属性禁用按钮并在方法处理时显示文本.


Aru*_*hny 11

尝试$ timeout(angularjs函数)

$timeout(function(){
    elm.attr('disabled',true);
}, 0)
Run Code Online (Sandbox Code Playgroud)

  • 可能应该使用`$ timeout`代替?即将$ timeout参数添加到指令函数然后使用`$ timeout(function(){elm.attr('disabled',true);},0);` (4认同)

Pas*_*aux 6

替代(灵活和简单)解决方案(灵感):围绕提交代码的包装函数,用于设置范围变量.查看实例.

控制器中的用法:

$scope.submit = mutexAction($scope, 'sending', submit);
Run Code Online (Sandbox Code Playgroud)

在视图中:

<form ng-submit="submit()">
  ...
  <button ng-disabled="sending">
    {{sending ? "Sending..." : "Send"}}
  </button>
</form>
Run Code Online (Sandbox Code Playgroud)

功能(把它放在服务中):

function mutexAction(scope, semaphoreName, action) {
  return function() {
    if (scope[semaphoreName]) {
      // not queuing action, forget it!
      return;
    }
    scope[semaphoreName] = true;
    action()['finally'](function () {
      scope[semaphoreName] = false;
    });
  };
}
Run Code Online (Sandbox Code Playgroud)